Django: Вопрос относительно запросов к таблице перекрестков/посреднической модели

Мой вопрос касается раздела many-to-many в документации django models:

Там упоминается, что с помощью промежуточной модели можно делать запросы к атрибутам промежуточной модели следующим образом:

Person.objects.filter(
    group__name='The Beatles',
    membership__date_joined__gt=date(1961,1,1))

Однако для другой модели "многие ко многим" (Group) аналогичный запрос приводит к FieldError:

# which groups have a person name containing 'Paul'?
Group.objects.filter(person__name__contains="Paul")

Однако запросы, которые явно ссылаются на таблицу перекрестков, работают:

Person.objects.filter(membership__group__name__contains="The Beatles")
Group.objects.filter(membership__person__name__contains="Paul")

Разве Group не должна иметь доступ к Person через модель соединения?

Модели:

from django.db import models

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

    def __str__(self):
        return self.name

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

    def __str__(self):
        return self.name

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

"Модель, определяющая поле ManyToManyField, использует имя атрибута самого поля, в то время как "обратная" модель использует строчное имя модели исходной модели, плюс '_set' (так же, как и обратные отношения "один-ко-многим")". (docs: Many-to-many relationships)

Так что вместо

Group.objects.filter(person__name__contains="Paul")

правильным запросом является

Group.objects.filter(members__name__contains="Paul")

поскольку связанная модель доступна через имя атрибута поля (а не модели).

Вернуться на верх