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

Django中models.TextChoices与models.IntegerChoices的区别及选型指南

两段代码的核心区别

两段代码都是Django的枚举类定义,核心差异是存储值的类型:

# Code 1 文本枚举
class YearInSchool(models.TextChoices):
    FRESHMAN = 'FR', _('Freshman')
    SOPHOMORE = 'SO', _('Sophomore')
    JUNIOR = 'JR', _('Junior')
    SENIOR = 'SR', _('Senior')
    GRADUATE = 'GR', _('Graduate')

继承自models.TextChoices,每个枚举的实际存储值是短字符串,搭配模型字段用CharField(max_length=2)即可。

# Code 2 整数枚举
class YearInSchool(models.IntegerChoices):
    FRESHMAN = 1, _('Freshman')
    SOPHOMORE = 2, _('Sophomore')
    JUNIOR = 3, _('Junior')
    SENIOR = 4, _('Senior')
    GRADUATE = 5, _('Graduate')

继承自models.IntegerChoices,每个枚举的实际存储值是整数,搭配模型字段常用PositiveSmallIntegerField。


为什么开发者更偏好TextChoices

首先你提到的「IntegerChoices搭配PositiveSmallIntegerField占用内存更小」其实是个认知误区:长度为2的CharField在绝大多数数据库中占用2字节存储空间,和PositiveSmallIntegerField的存储占用完全一致,两者的内存/存储成本几乎没有差异。
开发者偏好文本枚举的核心原因有几个:

  • 可读性极高:直接查询数据库时,看到FR就能立刻对应到大一,看到1还需要翻代码找枚举的映射关系,排查问题、写原生SQL的效率高很多,尤其是维护老项目或者跨团队协作时,不需要额外同步枚举映射规则。
  • 使用习惯延续:Django 3.0官方才推出内置的TextChoices和IntegerChoices,之前大家自定义枚举就普遍用文本元组的形式(('FR', 'Freshman'),...),切换到官方的TextChoices完全符合原有使用习惯,迁移成本为零。
  • 扩展性更强:后续如果要新增枚举值,文本枚举不需要考虑排序问题,比如要加预科阶段,直接新增PRE = 'PRE', _('Preparatory')即可,完全不影响已有数据;如果用整数枚举,插在最前面要么改原有所有枚举的数值,要么加个0值,很容易产生脏数据。
  • 对接成本更低:和前端、第三方系统交互时,文本值本身就有语义,不需要额外做一层「数字到含义」的映射,传参、联调时不容易出错。

两者的适用场景

优先用TextChoices的场景

  • 枚举值不需要参与数值计算
  • 希望直接查询数据库就能看懂字段含义
  • 后续可能会新增枚举值,不想修改已有数据
  • 需要和外部系统频繁交互

优先用IntegerChoices的场景

  • 枚举值需要参与数值运算,比如优先级、权重类的字段,需要拿值做排序、计算
  • 对接的外部系统明确要求使用整数类型的枚举值
  • 枚举值数量极多(上百个),确实需要压缩存储成本的极端场景

内容的提问来源于stack exchange,提问作者Ambitions

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:06:02