Зачем использовать аргумент" через " Для ManyToManyField в моделях Django?

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

пример:

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" группы? Разве "групповой" ForeignKey членства недостаточно, чтобы следить за отношением и получать доступ к этой информации?

4 ответов


Я думаю, что вы думаете об этом слишком буквально. Допустим, вы не использовать 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

Django, за кулисами, по существу создает для вас следующую модель:

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

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


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

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


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


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