Можно ли использовать 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 в качестве текущей базы данных.