Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model unique together both ways

Many questions already on this topic, but not what i'm searching for.

I have this Model:

class Options(TimeStampedModel)
    option_1 = models.CharField(max_length=64)
    option_2 = models.CharField(max_length=64)

    class Meta:
        unique_together = ('option_1', 'option_2')

Now I have a unique constraint on the fields. Is there a way to also define this the other way around so that it doesn't matter what was option_1 and what was option_2

As example:

Options.create('spam', 'eggs') # Allowed
Options.create('spam', 'eggs') # Not allowed
Options.create('eggs', 'spam') # Is allowed but should not be

Thanks in advance!

like image 952
Nebulosar Avatar asked Jan 28 '23 07:01

Nebulosar


1 Answers

I think a ManyToMany relation with a custom through table and an unique_together constraint on that table should do what you want.

Example code:

from django.db.models import Model, ForeignKey, ManyToManyField, CharField

class Option(Model):
    name = CharField()

class Thing(TimeStampedModel):
    options = ManyToManyField("Option", through="ThingOption")    

class ThingOption(Model):
    thing = ForeignKey(Thing)
    option = ForeignKey(Option)
    value = CharField()

    class Meta:
        unique_together = ('thing', 'option')

For Django 2.2+ it is recommended to use UniqueConstraint. In the docs there is a note stating unique_together may be deprecated in the future. See this post for its usage.

like image 192
etene Avatar answered Jan 31 '23 09:01

etene