这是一个从Django的官方文档:https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationshipsdjango:在多对多的关系中,多余的领域是否有黑魔法?
的模型是这样的:
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)
最后,它提供了这样一个例子:
# Find all the members of the Beatles that joined after 1 Jan 1961
>>> Person.objects.filter(
... group__name='The Beatles',
... membership__date_joined__gt=date(1961,1,1))
[<Person: Ringo Starr]
我的问题是人的模型是如何知道因为它们没有被定义在一个组和成员属性中。它只是通过许多方面的魔法,或者它是Django中的一种通用方法?
如果我要实现相同的查询,我想下面的代码更自然(从Django的ORM的角度,而不是从企业之一):
Membership.objects.filter(group__name='The Beatles', date_joined__gt=date(1961,1,1))).select_related('person')
编辑 我再次读取该文件,并做发现这种倒退是普遍的。在https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships中,它提到:
它也向后工作。要引用“反向”关系,只需使用模型的小写名称 。
我从来没有用过这个向后查询。所以我第一次看到它,它激怒了我的大脑。对不起,这个线程原来是愚蠢的。但我希望它能帮助那些跳过该段中非常细线的人。
我可以完全理解你的例子,因为乐队是在音乐家模型中定义的外键。但在我的问题中,Person模型没有定义人物属性。为了回答我的问题,请告诉我如何做相反的事情,比如Band.objects.filter(musician__name ='Ringo Starr')。 –
这是相同的基本机制。 django ORM将您的django查询转换为SQL。我将用一个例子来编辑。 –
感谢您的解释。我再次阅读文档并意识到反向查询是可能的。但它是一个单线的东西。所以我想我的眼睛刚刚跳过它。 –