如何为Django模型Choices枚举类添加第三个可访问的自定义属性?
不需要重写底层ChoicesMeta即可实现,自定义一个支持三属性的枚举基类即可,完整实现如下:
第一步:定义通用三属性Choices基类
from enum import Enum from django.db import models from django.utils.translation import gettext_lazy as _ class TripleChoices(models.ChoicesMixin, Enum): def __new__(cls, value, label, text): obj = object.__new__(cls) # 赋值核心属性,兼容Django原生Choices逻辑 obj._value_ = value obj.label = label # 自定义额外属性 obj.text = text return obj
第二步:业务代码使用
和期望的写法基本一致,直接继承上面的基类即可:
class Vehicle(models.Model): class VehicleType(TripleChoices): HONDA_CIVIC = 1, _("New car"), _("Vroom vroom") FORD_MODEL_T = 2, _("Old car"), _("not so fast") type = models.IntegerField(choices=VehicleType.choices, default=VehicleType.FORD_MODEL_T) # 可选:封装模型属性,避免每次手动转枚举 @property def type_obj(self): return self.VehicleType(self.type)
效果验证
# 直接访问枚举成员 print(VehicleType.HONDA_CIVIC.value) # 输出 1 print(VehicleType.HONDA_CIVIC.label) # 输出 New car print(VehicleType.HONDA_CIVIC.text) # 输出 Vroom vroom # 模型实例访问 vehicle = Vehicle.objects.create() print(vehicle.type_obj.text) # 输出 not so fast
说明
- 原有
choices属性完全兼容Django原生逻辑,不会影响表单、后台展示等功能 - 保留了int类型的value值,不需要改用TextChoices
- 之前自定义
__new__未生效大概率是没有正确继承ChoicesMixin,Django的Choices核心逻辑都由这个Mixin提供,和自定义枚举属性不冲突
内容的提问来源于stack exchange,提问作者af3ld
相关产品推荐
相关产品推荐

