开发者

Django: more complex uniqueness constraint?

开发者 https://www.devze.com 2023-04-02 22:26 出处:网络
In my model: class MyModel(models.Model): active = models.BooleanField() path = models.CharField(max_length = 512)

In my model:

class MyModel(models.Model):
  active = models.BooleanField()
  path = models.CharField(max_length = 512)

I would like to constrain that the 'path' attribute is unique amongst instances where active is True.

It seems like overriding save() might not work, as if two saves are done concurrent开发者_运维百科ly, both might pass the test and go ahead and save. Is there some trick or custom SQL (I'm using MySQL) I could use to have a conditional uniqness constraint like this at the database level?


What you are probably looking for is Model Validation. This was introduced in 1.2, and is quite well documented. Django Models Instances : Validating Objects

Whilst you may be able to write some tricky SQL to do this, as long as the database rows are all created through the Django ORM, then model validation is the more maintainable solution.

Aside: I'm interested in how you'd do it at the database level, short of having some level of pre-commit trigger. Uniqueness of one value dependent upon another being true is something I haven't seen a pattern for. Having a 2-field unique constraint on active+path would allow 1 false, 1 true and any number of NULL active rows for a given path value (assuming active is nullable, such as a NullBooleanField would provide).


Accidentally came across this whilst looking for something else, but for anyone else who ends up here, this is quite simple in Django >= 2.2 (which came out long after this question was asked) thanks to UniqueConstraint.

from django.db.models import Q, UniqueConstraint

class MyModel(models.Model):

    active = models.BooleanField()

    path = models.CharField(max_length=512)

    class Meta:
        constraints = [UniqueConstraint(fields=["path"], condition=Q(active=True)]
0

精彩评论

暂无评论...
验证码 换一张
取 消