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()
class FK(models.Model):
parent = models.ForeignKey('self', related_name='child')
>>> FK._meta.get_all_field_names()
['child', u'id', 'parent']
FK
的任何实例现在都可以通过fk.parent
和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
。情况似乎并非如此。
如何访问m2m.children
?
我正在使用Django 1.6.5。
正如Daniel Roseman's answer所说,设置symmetrical=False
可以解决问题。在Django ticket中,它被解释为:
在父母/子女的情况下,这种关系不是对称的 - 如果A是B的孩子,那么A并不是B的父母。
使用symmetrical=False
,related_name
中指定的反向关系就像在外键情况下一样创建:
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
答案 0 :(得分:4)
您需要设置symmetrical=False
。正如the documentation for ManyToManyField所说:
当Django处理这个模型时,它会识别出它自身有一个ManyToManyField,因此它不会向Person类添加person_set属性。相反,ManyToManyField被认为是对称的 - 也就是说,如果我是你的朋友,那么你就是我的朋友。
如果您不想在与self的多对多关系中进行对称,请将symmetrical设置为False。这将强制Django为反向关系添加描述符,允许ManyToManyField关系是非对称的。