Django:如何向后追随ManyToMany('self')

时间:2013-01-09 04:17:25

标签: django django-models many-to-many

class c(models.Model):
    f = models.ManyToManyField(
        'self', 
        blank=True, 
        null=True, 
        related_name='child_set'
    )

我能做到:

 c.objects.get(pk="1").f

但是如何通过'_set'获得?

 c.objects.get(pk="1").child_set

不起作用

我需要这个:

{name:A,parent:[]}
{name:B,parent:[A]}
{name:C,parent:[A,B]}

C.parent.all() == [A,B]
A.parent_set.all() == [B,C]

3 个答案:

答案 0 :(得分:0)

对于引用ManyToManyField的{​​{1}},不会创建反向关系。这是因为它没有用 - 它将包含所有引用自身的关系 - 这就是前向关系的作用。

无论您说什么self都应该设置为related_name,您都会发现(尾随%(field)s_rel_+会阻止正在创建的关系。)

所以答案是没有+,因为你可以使用child_set

答案 1 :(得分:0)

一个很好的解决方案是将C模型分解为两个模型,并为另一个创建OneToOneField。这样,结构就变成了树而不是网络。下面的代码说明了我的观点:

class Boo(models.Model):
    name = models.CharField(max_length=20)

class Coo(models.Model):
    boo = models.OneToOneField(Boo)
    foo = models.ManyToManyField(
          Boo, 
          blank=True, 
          null=True, 
          related_name='child_set'
    )

现在你可以做到:

Coo.objects.get(pk=1).foo

然后你可以通过'_set'获得:

Coo.objects.get(pk=1).boo.child_set

答案 2 :(得分:0)

默认情况下,Django的ManyToManyField是对称的。这意味着将同时创建双向模型。如果您指的是自我,这意味着没有反向关系,因为主要的关系包括两者。

可以通过禁用对称性来更改此行为。有一个关键字参数可以执行此调用symmetrical。在您的示例中:

class c(models.Model):
f = models.ManyToManyField(
    'self', 
    blank=True, 
    null=True, 
    related_name='child_set'
    symmetrical=False,
)