Можно ли использовать CheckConstraint на экземпляре модели в оболочке django?

У меня есть модель, и я хочу наложить на нее ограничение, чтобы гарантировать, что только разумные значения будут храниться в модели.

Модель вместе с ограничениями, которые я использую, выглядит примерно так (упрощенно)

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 и migrate выполнились успешно. Но, когда я пытаюсь создать новые экземпляры через оболочку, ограничение срабатывает в случаях, которые не должны были произойти. Я снова посмотрел на кодированное ограничение, и оно выглядит нормально.

Итак, я попытался разбить ограничение (constraint_on_et) на более простые условия, чтобы увидеть, какое из них действительно не работает. Поскольку таблица уже заполнена, я не могу проверить некоторые специфические части ограничения (они всегда должны срабатывать на текущих данных).

Из любопытства я подумал, не могу ли я применить CheckConstraint непосредственно к одному экземпляру модели, хранящемуся в базе данных, вместо того, чтобы применять его ко всей модели. В оболочке я смог легко создать объект CheckConstraint следующего вида:

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

Но после этого я не смог найти способ применить это к экземпляру Task. Посмотрел в интернете и в реализации CheckConstraint, но, похоже, нет способа для этого.

Итак, мой вопрос в том, есть ли способ, которым я могу достичь следующего? Если нет, есть ли альтернативы, которые я мог бы использовать?

Я могу сохранить копию текущей базы данных и провести тестирование на отдельной чистой базе данных, но это не всегда возможно.

Примечание: Я использую Django 3.2.10 с db.sqlite3 в качестве текущей базы данных.

Вернуться на верх