Зачем использовать «сквозной» аргумент для ManyToManyField в моделях Django? - PullRequest
6 голосов
/ 11 января 2012

Просматривая документы Django и пытаясь выяснить использование аргумента "through". Вот ссылка на документ .

Пример:

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

Зачем нужен атрибут "members" группы? Разве «иностранный ключ членства» группы не достаточно для того, чтобы следить за связью и получать доступ к этой информации?

Ответы [ 4 ]

10 голосов
/ 11 января 2012

Я думаю, вы слишком буквально думаете об этом.Допустим, вы не использовали through:

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person)

    def __unicode__(self):
        return self.name

За кулисами Джанго, по сути, создает для вас следующую модель:

class GroupPerson(models.Model)
    group = models.ForeignKey(Group)
    person = models.ForeignKey(Person)

Причиной создания модели Membership является добавление дополнительных данных, которые автоматически создаст модель Django , автоматически создающая , по умолчанию не будет, но, поскольку вы больше не используете значение по умолчанию, вы должны сообщить Django, что, используя through.По сути, вы сохраняете API, предоставляемый Django для ManyToManyFields.

3 голосов
/ 11 января 2012

Причина, по которой можно так поступить, заключается в том, что у Группы есть поле для этих отношений, а не для того, чтобы проследовать за отношениями обратно через ее members_set.

Если ничего другого, это может упростить написание запросов. По крайней мере, это может облегчить жизнь программиста и облегчить чтение кода. Достаточно оптимизирующий ORM сможет генерировать соответствующие индексы для ускорения такого доступа (и, если я не очень сильно ошибаюсь, django действительно делает это; или, по крайней мере, Саут делает).

2 голосов
/ 11 января 2012

Это так, что из группы вы можете получить прямой доступ к членам. Вы не обязательно хотите иметь дело с объектами Членства напрямую (пользователь может их даже не видеть). Вам просто нужны группы с некоторой дополнительной информацией. Думайте о членстве как о метаданных об ассоциации между человеком и группой.

1 голос
/ 11 января 2012

сквозные таблицы используются для хранения свойств отношения , в данном случае, например, даты, к которой Person присоединился к конкретному Group

...