'Is it possible to use CheckConstraint on model instance in the django shell?

I have a model and want to apply a constraint on it to ensure only sensible values get to be stored in the model.

The model along with the constraint I am using looks somewhat like this (simplified)

from django.db import models

class Task(models.Model):

    ACTION_CHOICES = (
        ('UnderWay', 'UnderWay'),
        ('Processed', 'Processed'),
        ('Entrusted', 'Entrusted')
    )

    action = models.CharField(max_length=20, default='UnderWay', choices=ACTION_CHOICES)
    entrusted_to = models.CharField(max_length=20, help_text='Name of the department/person entrusted to')
    # some other fields

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=(
                    (models.Q(action='Entrusted') & (models.Q(entrusted_to__isnull=False) | ~models.Q(entrusted_to=''))) |
                    ((models.Q(action='UnderWay') | models.Q(action='Processed')) & (models.Q(entrusted_to__isnull=True) | models.Q(entrusted_to='')))
                ), #more complex conditions in actual
                name='constraint_on_et'
            )
        ]

    def __str__(self):
        return f'{self.id} - {self.action}'

Makemigrations and migrate ran successfully. But, when I try to create new instances through the shell, the constraint fails in cases that weren't meant to be. I looked at the coded constraint again and it looks fine to me.

So, I tried to break the constraint(constraint_on_et) into simpler conditions to see which one actually fails. As the table is already populated, I am not able to check some specific parts of the constraint(they are always meant to fail on current data).

Out of curiosity, I thought if I could apply a CheckConstraint, directly on a single instance of the model stored in the database rather than applying it on the whole model. On the shell, I was able to easily create a CheckConstraint object like:

c = models.CheckConstraint(
        check=(
            (models.Q(action='Entrusted') & (models.Q(entrusted_to__isnull=False) | ~models.Q(entrusted_to='')))
        ),
        name='temp_constraint'
    )

But, after this, I couldn't see a way to apply this on a Task instance. Looked over the internet and into the implementation of CheckConstraint, but there doesn't seem to be a way for it.

So, my question is, is there any way I could achieve the following? If not, are there any alternatives I could use?

I can save a copy of the current database and test on a separate clean one, but that might not be always feasible.

Note: I am using Django 3.2.10 with db.sqlite3 as the current database.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source