You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:54:03