递归多对多关系的相关名称不起作用 [英] Related name for recursive many to many relationship not working
问题描述
class A(models.Model):
pass
class B(models.Model):
parents = models.ManyToManyField(A, related_name='children')
>>> A._meta.get_all_field_names()
['children', u'id']
>>> B._meta.get_all_field_names()
[u'id', 'parents']
我可以得到 a.children.all()
和 b.parents.all()
的模型实例的孩子和父母的集合
I can get the sets of children and parents of model instances with a.children.all()
and b.parents.all()
class FK(models.Model):
parent = models.ForeignKey('self', related_name='child')
>>> FK._meta.get_all_field_names()
['child', u'id', 'parent']
现在,任何 FK
实例都可以使用 fk.parent
和<$ c来获取其父项和子项。 $ c> fk.child
Any instance of FK
will now be able to get both its parent and its child with fk.parent
and fk.child
class M2M(models.Model):
parents = models.ManyToManyField('self', related_name='children')
>>> M2M._meta.get_all_field_names()
[u'id', 'parents']
,就像我可以访问 a.children
和 fk.child
一样,我也可以访问 m2m.children
。
One would expect that, like I could access a.children
and fk.child
, I would also be able to access m2m.children
. This seems to not be the case.
我如何访问 m2m.children
?
我正在使用Django 1.6.5。
I'm using Django 1.6.5.
以 Daniel Roseman的答案说,设置 symmetrical = False
可以解决此问题。在 Django票证中,解释为:
As Daniel Roseman's answer said, setting symmetrical=False
solves the problem. In a Django ticket it is explained as:
对于父母/孩子,这种关系不是对称的-如果A是B的孩子,那么就不会得出A是B的父母的情况。
In the case of parent/child, the relationship isn't symmetrical - if A is a child of B, it doesn't follow that A is a parent of B.
使用 symmetrical = False
,在 related_name
中指定的反向关系为就像在外键情况下创建的一样:
With symmetrical=False
, the reverse relation specified in the related_name
is created just like in the foreign key case:
class M2M(models.Model):
parents = models.ManyToManyField('self', related_name='children', symmetrical=False)
>>> M2M._meta.get_all_field_names()
[u'id', 'parents', children]
>>> parent.children.add(child)
>>> parent.children.all() # returns QuerySet containing the child
>>> child.parents.all() # returns QuerySet containing the parent
的QuerySet
推荐答案
您需要设置 symmetrical = False
。作为 ManyToManyField的文档说:
当Django处理此模型时,它会识别出其自身具有ManyToManyField,因此不会添加person_set属性到Person类。取而代之的是,ManyToManyField假定是对称的,也就是说,如果我是你的朋友,那么你就是我的朋友。
When Django processes this model, it identifies that it has a ManyToManyField on itself, and as a result, it doesn’t add a person_set attribute to the Person class. Instead, the ManyToManyField is assumed to be symmetrical – that is, if I am your friend, then you are my friend.
如果您不希望与以下对象的多对多关系对称自我,将对称设置为False。这将迫使Django为反向关系添加描述符,从而允许ManyToManyField关系是非对称的。
If you do not want symmetry in many-to-many relationships with self, set symmetrical to False. This will force Django to add the descriptor for the reverse relationship, allowing ManyToManyField relationships to be non-symmetrical.
这篇关于递归多对多关系的相关名称不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!