如何继承Django自定义Choice类扩展选项并解决迁移E005错误
问题原因
你当前实现抛出错误的核心问题是拼接choices时生成了嵌套元组结构,不符合Django字段要求的(实际值, 可读名称)单层元组迭代规则:
你原来的写法得到的choices结构为:
((('private_user', 'Private User'), ('public_user', 'Public User')), ('other_choice', 'Other choice'))
父类返回的整个元组被当成了新元组的第一个元素,两层嵌套的结构触发了fields.E005报错。
正确实现方案
利用Python的元组解包语法*将父类返回的choices元组展开,再拼接新增的选项即可:
from django.utils.translation import ugettext_lazy as _ class ExtendedChoices(UserChoices): OTHER_CHOICE = "other_choice" # 其他20+新增选项可以在此处继续定义 ANOTHER_CHOICE = "another_choice" @classmethod def choices(cls): return ( # 用*解包父类的所有选项,自动展开到当前元组层级 *super().choices(), # 下方依次添加新增的选项元组即可 (cls.OTHER_CHOICE, _("Other choice")), (cls.ANOTHER_CHOICE, _("Another choice")), )
方案优势
- 无需修改原有父类代码,完全符合继承扩展的逻辑
- 新增选项直接按格式追加即可,哪怕父类有40+选项、扩展类加20+选项也能正常拼接
- 生成的choices是符合Django要求的单层元组结构,迁移和字段校验都能正常通过
内容的提问来源于stack exchange,提问作者andrepz
相关产品推荐
相关产品推荐

