0

I have a model named Tag, with a ManyToManyField named parents:

parents = models.ManyToManyField('self', blank=True, symmetrical=False)

When I have a tag tag2 and try to add parent tag1 to it, Django seems to treat the relationship as symmetrical, when I need it to be asymmetrical. To be specific, when I run this code:

tag1 = Tag.objects.get(name='Academic')
tag2 = Tag.objects.get(name='Accounting')

tag1.parents.clear()
tag2.parents.clear()
print("Before:")
print("Tag1 has these parents:", tag1.parents.all())
print("Tag2 has these parents:", tag2.parents.all())

tag2.parents.add(tag1)
print("After:")
print("Tag1 has these parents:", tag1.parents.all())
print("Tag2 has these parents:", tag2.parents.all())

tag1.parents.clear()
print("Lastly:")
print("Tag1 has these parents:", tag1.parents.all())
print("Tag2 has these parents:", tag2.parents.all())

This is the output:

After first clearing:
Tag1 has these parents: <QuerySet []>
Tag2 has these parents: <QuerySet []>
After adding parent:
Tag1 has these parents: <QuerySet [<Tag: Accounting>]>
Tag2 has these parents: <QuerySet [<Tag: Academic>]>
After clearing again:
Tag1 has these parents: <QuerySet []>
Tag2 has these parents: <QuerySet []>

I need tag1 to be a parent of tag2, but not vice versa. I'm able to make this happen through the admin interface, but I can't seem to do it in code. This seems like it should be a very basic and common function, so I'm confused as to why it's misbehaving.

John Qian
  • 123
  • 9
  • Why are you passing `symmetrical` keyword argument in the statement: tag2.parents.add(tag1, symmetrical=False) – Mohammad Mustaqeem Nov 16 '17 at 05:59
  • @MohammadMustaqeem My bad, this was me tampering around; that wasn't actually in the code I ran. I've edited my question to remove it. – John Qian Nov 16 '17 at 06:30
  • Can you try by removing `symmetrical=False` from ManyToManyField. By default, it is False. Don't forget to run `makemigrations` and `migrate` – Mohammad Mustaqeem Nov 16 '17 at 06:34
  • 1
    @MohammadMustaqeem The ManyToManyField originally didn't have symmetrical=False. I added it because the Django docs say it defaults to True. My migration was run; like I said, I'm able to make the relation asymmetrical through the admin interface. It seems like the problem is in the add() function itself. – John Qian Nov 16 '17 at 06:43
  • @MohammadMustaqeem One tag can have multiple parents. I suppose I could reduce it to one parent per tag, but I would prefer not to if possible. – John Qian Nov 16 '17 at 07:03
  • Can you create new objects and instead of getting the older objects. I just read the answer https://stackoverflow.com/a/19891950/4772392. It has beautifully explained the concept. – Mohammad Mustaqeem Nov 16 '17 at 07:09
  • @MohammadMustaqeem Thank you so much, I'm not sure how I didn't encounter that link in my search. I wiped the database and re-migrated, now everything's working fine. – John Qian Nov 16 '17 at 08:22

0 Answers0