How to allow boolean True on just one model in table in Django?

100 views Asked by At

I've got a model where I would like there to be able to have one set as the 'app default'.

In this model I added a field named is_app_default in order to help accommodate this.

class TreeLevel(models.Model):
    id = models.BigAutoField(primary_key=True)
    short_description = models.CharField(max_length=200)
    long_description = models.TextField()
    is_app_default = models.BooleanField(default=False)

    class Meta:
        verbose_name = "Tree Level"
        verbose_name_plural = "Tree Levels"

class Layer(models.Model):
    id = models.BigAutoField(primary_key=True)
    tree_levels = models.ManyToManyField(TreeLevel)
    description = models.TextField()

    class Meta:
        verbose_name = "Layer"
        verbose_name_plural = "Layers"

The Layer model links to TreeLevel with an m2m. Ultimately I would like the is_app_default TreeLevel automatically added to every Layer m2m relationship - which is why there can only be one TreeLevel with is_app_default set as True.

My potential solution(s):

Users with admin may be creating new TreeLevel objects - so I need to make sure they aren't setting that Boolean in any new models. I think I can override the save() method on TreeLevel to check the DB to see if another with that boolean as True exists - if so? Don't save the 'new' one and return an error. But I think this hits the database - causing unnecessary queries potentially?

Then additionally, I would also need to override the save() method on Layer and add the 'default' TreeLevel to that many2many at that time.

Is there a good way to 'automatically' handle this with these relationships?

My ultimate goal:

Have a default TreeLevel that is automatically added to every Layer many to many relationship whenever a Layer is created.

Questions:

Would my proposed solution work?

I've tried looking into Djangos Unique Constraints, but I think those are more on a row level, as opposed to a Table level.

0

There are 0 answers