Django: How to follow ManyToMany('self') backwards

情到浓时终转凉″ 提交于 2019-12-11 04:06:56

问题


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

I can do :

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

But how do I get by '_set'?

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

doesn't work

i need this:

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

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

回答1:


For ManyToManyFields that reference self, a reverse relationship is not created. This is because it has no use - it would contain all relations that refer to itself - which is what the forward relation does.

You'll find regardless of what you say the related_name should be it will be set to %(field)s_rel_+ (the trailing + prevents the relation being created).

So the answer is there is no child_set because you can just use f.




回答2:


A good solution for this is to break the C model into two models and create a OneToOneField to the other. This way, the structure becomes a tree rather than a web. The code below illustrates my point:

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'
    )

Now you can do:

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

And then you can get by '_set' with:

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



回答3:


Django's ManyToManyField is symmetrical by default. That means that the though model will be created both ways. If you are pointing to self this means there is not reverse relationship, since the main one includes both.

The this behavior can be changed by disabling the symmetry. There is a keyword argument to do that call symmetrical. In your example:

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


来源:https://stackoverflow.com/questions/14228193/django-how-to-follow-manytomanyself-backwards

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!