Django Constraints


As of Django 2.2, you can add database constraints to your models.  I find database constraints extremely valuable and one of those few features that Django really needed.

This blog post is more of a quick reference for myself when adding constraints to my Django models

Django has support for both CheckConstraints and UniqueConstraints.  You'll need to add your constraints to your models Meta.constraints like below.

class Meta:
  constraints = [
     UniqueConstraint(fields=['field1'],
                      condition=Q(field2=True),
                      name='unique_field')
  ]

CheckConstraints

When adding CheckConstaints you're required to provide the check and the name of the constraint.  The check kwarg on the CheckConstraint is where you'll put your database constraint.  When you're creating your check you'll want to use the Q object to specify the check.  The syntax for the constraint in the Q object is similar to the syntax you would use when building a django query. 

CheckConstraint(check=Q(number_of_doors__gte=2, name='car_door_minimum')

In our example above the CheckConstraint will ensure no object will be created in your datbase table that has less than 2 doors.

UniqueConstraint

The UniqueConstraint is similar to the CheckConstraint but here you'll add conditions against fields to ensure their uniquness.  This gives you a little more flexibility than using the unique keyword on a model field or with unique_together.  This constraint allows you to add conditionals to generate uniqueness within your database table.

When adding a UniqueConstraint you'll need to add a list of fields that apply to the constraint, your condition and the name of the constraint.  A very simple example is ensuring something only has a single "active" record.  

UniqueConstraint(fields=['store'], condition=Q(active=True), name='active_store')