Django Choice字段混用文本与整数 新增整数属性报错如何解决
问题原因分析
你遇到的报错核心原因是:Django的TextChoices/IntegerChoices继承自Python标准库的Enum类,默认会把类内部所有大写命名的属性识别为枚举成员,而不是普通类属性。你定义的MAX_LENGTH = 2被识别成了States枚举的一个成员,所以States.MAX_LENGTH取到的不是整数2,而是<States.MAX_LENGTH>枚举实例,和整数比较的时候自然触发类型错误。
解决方案
方法1:用@nonmember标记非枚举成员
Python的enum模块提供了@nonmember装饰器,可以明确标记某个属性不属于枚举成员,会保留原本的类型:
from enum import nonmember from django.db import models class States(models.TextChoices): ALABAMA = 'AL', 'Alabama' ALASKA = 'AK', 'Alaska' # 其余州的定义省略 WISCONSIN = 'WI', 'Wisconsin' WYOMING = 'WY', 'Wyoming' @nonmember MAX_LENGTH = 2 class PersonalInfo(models.Model): state = models.CharField(max_length=States.MAX_LENGTH, choices=States.choices, default=States.ALABAMA)
方法2:封装为类方法返回固定值
也可以把配置类属性封装成类方法,避免被识别为枚举成员:
from django.db import models class States(models.TextChoices): ALABAMA = 'AL', 'Alabama' ALASKA = 'AK', 'Alaska' # 其余州的定义省略 WISCONSIN = 'WI', 'Wisconsin' WYOMING = 'WY', 'Wyoming' @classmethod def get_max_length(cls): return 2 class PersonalInfo(models.Model): state = models.CharField(max_length=States.get_max_length(), choices=States.choices, default=States.ALABAMA)
混合文本、整数类型的选项/属性实现
如果你需要在同一个选项类中同时存在文本类型、整数类型的选项值,不要使用TextChoices或IntegerChoices(这两个类会强制校验所有选项值的类型),直接继承Django的基础Choices类即可:
from enum import nonmember from django.db import models class MixedChoices(models.Choices): # 整数类型选项 STATUS_ACTIVE = 1, "激活" STATUS_INACTIVE = 0, "未激活" # 字符串类型选项 TYPE_PERSONAL = "personal", "个人账号" TYPE_ENTERPRISE = "enterprise", "企业账号" # 也可以按上面的方法加自定义非选项属性 @nonmember CUSTOM_INT_CONFIG = 123 @nonmember CUSTOM_STR_CONFIG = "custom"
如果只是加自定义的非选项属性,不管是整数还是文本类型,用上面的@nonmember方法标记即可,不需要修改继承的父类。
内容的提问来源于stack exchange,提问作者Amistad
相关产品推荐
相关产品推荐

