Issue with Django CheckConstraint
I'm trying to add some new fields to an existing model and also a constraint related to those new fields:
class User(models.Model):
username = models.CharField(max_length=32)
# New fields ##################################
has_garden = models.BooleanField(default=False)
garden_description = models.CharField(
max_length=32,
null=True,
blank=True,
)
class Meta:
constraints = [
models.CheckConstraint(
check=Q(has_garden=models.Value(True))
& Q(garden_description__isnull=True),
name="garden_description_if_has_garden",
)
]
The problem is that when I run my migrations I get the following error:
django.db.utils.IntegrityError: check constraint "garden_description_if_has_garden" is violated by some row
But I don't understand how the constraint is being violated if no User
has a has_garden
, the field is just being created and also its default value is False
🤔.
I'm using django 3.2 with postgresql.
What is the proper way to add this constraint? If it's of any use here's the autogenerated migration:
# Generated by Django 3.2.25 on 2025-01-15 23:52
import django.db.models.expressions
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("some_app", "0066_user"),
]
operations = [
migrations.AddField(
model_name="user",
name="garden_description",
field=models.CharField(blank=True, max_length=32, null=True),
),
migrations.AddField(
model_name="user",
name="has_garden",
field=models.BooleanField(default=False),
),
migrations.AddConstraint(
model_name="user",
constraint=models.CheckConstraint(
check=models.Q(
("has_garden", django.db.models.expressions.Value(True)),
("garden_description__isnull", True),
),
name="garden_description_if_has_garden",
),
),
]
Here we add a constraint to either check if has_garden is true and garden_description is not null, or if has_garden is false and garden_descriptionn is null
class User(models.Model):
username = models.CharField(max_length=32)
# New fields ##################################
has_garden = models.BooleanField(default=False)
garden_description = models.CharField(
max_length=32,
null=True,
blank=True,
)
class Meta:
constraints = [
models.CheckConstraint(
check=(
Q(has_garden=models.Value(True))
& Q(garden_description__isnull=False)
| (
Q(has_garden=models.Value(False))
& Q(garden_description__isnull=True)
)
),
name="garden_description_if_has_garden",
)
]