Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make recursive ManyToManyField relationships that have extra fields symmetrical in Django?

class Food_Tag(models.Model):
    name = models.CharField(max_length=200)
    related_tags = models.ManyToManyField('self', blank=True, symmetrical=False, through='Tag_Relation')

    def __unicode__(self):
     return self.name

class Tag_Relation(models.Model):
    source = models.ForeignKey(Food_Tag, related_name='source_set')
    target = models.ForeignKey(Food_Tag, related_name='target_set')
    is_a = models.BooleanField(default=False); # True if source is a target
    has_a = models.BooleanField(default=False); # True if source has a target

I want to be able to get the relations between Food_Tags like:

>>> steak = Food_Tag.objects.create(name="steak")
>>> meat = Food_Tag.objects.create(name="meat")
>>> r = Tag_Relation(source=steak, target=meat, is_a=True)
>>> r.save()
>>> steak.related_tags.all()
[<Food_Tag: meat>]
>>> meat.related_tags.all()
[]

but related_tags is empty for meat. I realize this has to do with the 'symmetrical=False' argument, but how can I set up the model such that 'meat.related_tags.all()' returns all related Food_Tags?

like image 377
kliao Avatar asked Nov 09 '10 00:11

kliao


1 Answers

As mentioned in the docs:

  • When defining a many-to-many relationship from a model to itself, using an intermediary model, you must use symmetrical=False (see the model field reference).

Thus, it is not (yet?) possible to have a symmetrical, recursive many-to-many relationship with extra fields, in Django. It's a "pick two" sorta deal.

like image 65
eternicode Avatar answered Sep 23 '22 09:09

eternicode