Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django postgres conditional constrain

I'm trying to set a conditional unique constrain to one of my model field (column on db perspective) with respect to another boolean field but can't find a way to do it.

I'm creating a web management tool, to aid/control custumers atendance, based on numbered cards while they are still on the store. My main objective is to prevent my user to save an card number while this number is still active (aka boolean field) with another custumer.
Something like this on models.py:

    class Cards(models.Model):
         card_number = models.PositiveIntegerField("""{{RESTRICTION NEEDED}}""")
         card_date = models.DateTimeField(auto_now=False, auto_now_add=True)
         custumer = models.ForeignKey(Customer)
         status = models.BooleanField(default=False)

maybe something like this would work directly on postgres, didn't tried yet

CREATE UNIQUE INDEX card_number_ind ON Cards (card_number) WHERE (status is False);

Any chance to do it directly with Django? I mean set a conditional unique constrain with respect to a boolean field (status) on Django?

TIA
Obs.This is my first question ever on stackoverflow, feel free to criticize on style.

like image 831
Felício Avatar asked Feb 03 '16 20:02

Felício


2 Answers

Django doesn't support defining conditional constraints in models.py, however you can create a migration to add such a constraint.

Start by creating an empty migration

./manage.py makemigrations appname --empty

This will create an empty migration file. Next, you'll want to add your custom constraint to the migration

class Migration(migrations.Migration):

    ... 

    operations = [
        migrations.RunSQL('create unique index card_number_ind on cards (card_number) where (status is false)'),
    ]
like image 160
Derek Kwok Avatar answered Oct 05 '22 23:10

Derek Kwok


Starting in Django 2.2 there is now a UniqueConstraint declaration available that has a condition option.

condition

UniqueConstraint.condition

A Q object that specifies the condition you want the constraint to enforce.

For example:

UniqueConstraint(fields=['user'], condition=Q(status='DRAFT'), name='unique_draft_user')

ensures that each user only has one draft.

like image 23
rrauenza Avatar answered Oct 06 '22 00:10

rrauenza