问题
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 ManyToManyField
s 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