Consider the following model.
class MyModel(models.Model):
a = models.DateField(blank=True, default=None, null=True)
b = models.DateField(blank=True, default=None, null=True)
I'd like to require that both a and b are NULL, or both are NOT NULL. I can express this in raw DDL:
ALTER TABLE "app_mymodel" ADD CONSTRAINT "both_or_none_null" CHECK ((a IS NULL) = (b IS NULL));
To get this through Django, I tried
class Meta:
constraints = [
models.CheckConstraint(
check=Q(a__isnull=F('b__isnull')),
name='both_or_none_null'
)
]
Alas, this produces django.core.exceptions.FieldError: Joined field references are not permitted in this query when I try to apply the resulting migration. I have therefore resorted to the less succinct
check=(Q(a__isnull=True) & Q(b__isnull=True)) | (Q(a__isnull=False) & Q(b__isnull=False))
which generates a correspondingly clunky DDL constraint. But my Django-foo is limited, so is there a way to express the original constraint correctly?
This should do it: