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)
            )
        ]
Вернуться на верх