Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How am I misunderstanding Django's get_or_create function?

We have a Django project that has a bunch of experiments, and each experiment can have zero or more text tags. The tags are stored in a table, and there is a many-to-many relationship between experiments and tags:

class Tag(models.Model):
    text = models.TextField(max_length=32, null=False, validators=[validate_unicode_slug], db_index=True, unique=True)

class Experiment(models.Model):
    ...
    tags = models.ManyToManyField(Tag)

If I add a tag to an experiment with get_or_create() it does the right thing, filling in the tag table and the joining table. If I remove the tag from the experiment with remove() it also does the right thing by removing just the row from the joining table and leaving the tag table intact. But if I later come to re-add the tag to the experiment, it throws a uniqueness constraint error because it’s trying to re-add the tag to the tag table. E.g:

    tag, created = experiment.tags.get_or_create(text="B")
    experiment.tags.remove(*experiment.tags.filter(text="B"))
    tag, created = experiment.tags.get_or_create(text="B")  # It fails the uniqueness test here.

Removing the uniqueness constraint just means it adds a new tag with identical text.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

So is it possible to add and remove tags arbitrarily by just modifying the joining table if a tag already exists?

>Solution :

Seperate this process, because it’s not that simple with relations.

tag, created = experiment.tags.get_or_create(text="B")
experiment.tags.remove(*experiment.tags.filter(text="B"))
tag, created = Tag.objects.get_or_create(text="B")
experiment.tags.add(tag)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading