Django:在 Meta class 中使用嵌套的 TextChoice class 值

Django: Using a nested TextChoice class values in a Meta class

我曾经像这样在模型 class 中声明 TextChoices classes:

class Order(models.Model):
    class OrderStatusChoices(models.TextChoices):
        NEW = 'NEW'
        CLOSED = 'CLOSED'
        CANCELLED = 'CANCELLED'
        
    status = models.CharField(choices=OrderStatusChoices.choices, max_length=9)

在这种情况下,我将 class 实例化为:

from models import Order

order = Order(status=Order.OrderStatusChoices.NEW)

现在我需要使用 Meta class 中的 TextChoices 值来检查数据库约束:

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)
            )
        ]

但是,如果状态 class 嵌套在订单 class 中,则无法引用文本选择(未解决的引用 'OrderStatusChoices' )。 这可以通过将状态 class 从顺序 class:

中取出来解决
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)
            )
        ]

但这并不能很方便地导入(对我来说,也许我错了,这是正常的)没有状态文本选择的订单模型,以及为了创建订单的实例 class ,您需要同时导入订单模型和状态文本选择:

from models import Order, OrderStatusChoices

order = Order(status=OrderStatusChoices.NEW)

万一模型少,textchoices少,你还可以记住这个,做这样的导入,但我想如果项目变大,就相当inconvenient.Incase there few models 和 textchoices 很少,你还可以记住这个并执行这样的导入,但我认为如果项目变大,会很不方便。

告诉我,在 Meta class 中使用 textchoice 值还有其他选择吗?

作为一种可能的解决方法,您可以将外部 class 显式分配给具有相同名称的 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)
            )
        ]