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")
поскольку связанная модель доступна через имя атрибута поля (а не модели).