Home > Mobile >  Django: constraint with nullable multiple field conditions
Django: constraint with nullable multiple field conditions

Time:03-29

I have a model in Django/PostgreSQL project and want to add following constraints to three nullable fields: either all fields are NULL, either all of them aren't.

Here's code (simplified):

class SomeModel(models.Model):
    ...
    a = models.IntegerField(nullable=True)
    b = models.DateTimeField(nullable=True)
    c = models.DateTimeField(nullable=True)
    ...

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=(
                    (Q(a__isnull=True) & Q(b__isnull=True) & Q(c__isnull=True)) |
                    (Q(a__isnull=False) & Q(b__isnull=False) & Q(c__isnull=False))
                )
            )
        ]

If I understand correctly, I've just described two possible states of those three fields. First is "all three are NULL", second is "none of them are NULL".

But what I got, actually, is "none of them can be NULL". Django admin panel insists on filling all of the fields, they all are mandatory. How can I fix this behaviour? Thanks!

CodePudding user response:

This is not due to the constraints, you should specify blank=True [Django-doc] when you want to allow to leave form fields blank, and thus default to None/NULL:

class SomeModel(models.Model):
    # …
    a = models.IntegerField(null=True, blank=True)
    b = models.DateTimeField(null=True, blank=True)
    c = models.DateTimeField(null=True, blank=True)

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=Q(a=None, b=None, c=None) |
                      Q(a__isnull=False, b__isnull=False, c__isnull=False),
                name='all_or_none_null'
            )
        ]
  • Related