Django: Использование значений вложенного класса TextChoice в классе Meta
Раньше я объявлял классы TextChoices внутри класса модели следующим образом:
class Order(models.Model):
class OrderStatusChoices(models.TextChoices):
NEW = 'NEW'
CLOSED = 'CLOSED'
CANCELLED = 'CANCELLED'
status = models.CharField(choices=OrderStatusChoices.choices, max_length=9)
В этом случае я инстанцировал класс следующим образом:
from models import Order
order = Order(status=Order.OrderStatusChoices.NEW)
Теперь мне нужно использовать значения TextChoices в классе Meta для проверки ограничения базы данных:
class Order(models.Model):
class OrderStatusChoices(models.TextChoices):
NEW = 'NEW'
CLOSED = 'CLOSED'
CANCELLED = 'CANCELLED'
status = models.CharField(choices=OrderStatusChoices.choices, max_length=9)
class Meta:
constraints = [
models.CheckConstraint(
name='%(app_label)s_%(class)s_status_valid',
check=models.Q(status__in=OrderStatusChoices.values)
)
]
Однако, если класс статуса вложен в класс заказа, на textchoice нельзя сослаться (Unresolved reference 'OrderStatusChoices' ). Это можно решить, если вынести класс статуса из класса заказа:
class OrderStatusChoices(models.TextChoices):
NEW = 'NEW'
CLOSED = 'CLOSED'
CANCELLED = 'CANCELLED'
class Order(models.Model):
status = models.CharField(choices=OrderStatusChoices.choices, max_length=9)
class Meta:
constraints = [
models.CheckConstraint(
name='%(app_label)s_%(class)s_status_valid',
check=models.Q(status__in=OrderStatusChoices.values)
)
]
Но это делает не очень удобным импорт (для меня, может я ошибаюсь и это нормально) модели заказа без status textchoice и чтобы создать экземпляр класса заказа, нужно импортировать и модель заказа и status textchoice:
from models import Order, OrderStatusChoices
order = Order(status=OrderStatusChoices.NEW)
В случае, если моделей немного и у них мало textchoices, вы все равно можете запомнить это и выполнить такой импорт, но я думаю, если проект станет большим, это будет довольно неудобно.
В случае, если моделей немного и у них мало textchoices, вы все равно можете запомнить это и выполнить такой импорт, но я думаю, если проект станет большим, это будет довольно неудобно.Скажите, есть ли другие варианты использования значений textchoice в классе Meta?
В качестве возможного обходного пути вы можете явно присвоить внешний класс одноименному атрибуту Order
, тогда вы сможете получить к нему доступ обоими способами.
class OrderStatusChoices(models.TextChoices):
...
class Order(models.Model):
OrderStatusChoices = OrderStatusChoices
...
class Meta:
constraints = [
models.CheckConstraint(
name='%(app_label)s_%(class)s_status_valid',
check=models.Q(status__in=OrderStatusChoices.values)
)
]