递归多对多关系的相关名称不起作用 [英] Related name for recursive many to many relationship not working

查看:73
本文介绍了递归多对多关系的相关名称不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆