class MyTypes(TextChoices):
MINE_AAA = '1', 'a',
MINE_BBB = '2', 'b',
MINE_CCC = '3', 'c',
MINE_DDD = '4', 'd',
MINE_EEE = '5', 'e'
my_type = models.CharField(max_length=1, choices=MyTypes.choices)
我一直在努力在我的模型中使用选项。在上面的例子中,如果我创建一个实例“my_obj”并将“my_obj.my_type”设置为“MyTypes.MINE_BBB”,那么如果我查看“my_obj”,它的类型是MyTypes。但是,如果我稍后查询“my_obj”并查看“my_obj.my_type”,它的类型现在是字符串。
因此,当我最初创建对象并序列化它时,序列化程序需要处理 MyTypes,但是如果我在查询后序列化该值,序列化程序需要处理字符串。
使用 TextChoices 字段时,我真正期望的是存储在数据库中的值将是单个字符,但是当我在代码中引用它时,我会看到我的 MyTypes。
当我们引用模型时,我们不应该取回 TextChoices 实例吗?如果没有,最简单的获取方法是什么?看起来,如果我在迭代 MyTypes.choices 来获取它之后,它确实没有提供太多价值。
这是文档的样子。
class YearInSchool(models.TextChoices):
FRESHMAN = 'FR', _('Freshman')
SOPHOMORE = 'SO', _('Sophomore')
JUNIOR = 'JR', _('Junior')
SENIOR = 'SR', _('Senior')
GRADUATE = 'GR', _('Graduate')
您可以像这样获取
MyTypes
实例:
MyTypes('1') == MyTypes.MINE_AAA
因此,在您的代码中,每当您想要
my_obj
的类型时,作为 MyTypes 实例,您都可以执行 MyType(my_obj.my_type)
。
我建议为其编写一个方法:
class MyModel(models.model):
class MyType(TextChoices):
...
my_type = models.CharField(max_length=1, choices=MyTypes.choices)
def get_type(self):
return MyModel.MyType(self.my_type)
选择字段需要是元组列表
class MyTypes(TextChoices):
MINE_AAA = ('1', 'a',)
MINE_BBB = ('2', 'b',)
MINE_CCC = ('3', 'c',)
MINE_DDD = ('4', 'd',)
MINE_EEE = ('5', 'e')
MY_CHOICES = [
MINE_AAA,
MINE_BBB,
MINE_CCC,
MINE_DDD,
MINE_EEE
]
my_type = models.CharField(max_length=1, choices=MY_CHOICES)
这是文档的样子。
class YearInSchool(models.TextChoices):
FRESHMAN = 'FR', _('Freshman')
SOPHOMORE = 'SO', _('Sophomore')
JUNIOR = 'JR', _('Junior')
SENIOR = 'SR', _('Senior')
GRADUATE = 'GR', _('Graduate')
用于性别选择的TextChoice,首先你必须导入
从 django.utils.translation 导入 gettext_lazy as _
class Gender(models.TextChoices):
MALE = "male", _("Male")
FEMALE = "female", _("Female")
OTHER = "other", _("Other")
由于您从
MyTypes
继承了 TextChoices
,因此字段 my_type
可能会出现损坏的行为。
在文档中创建了本地类
class MyModel(models.Model):
class MyTypes(models.TextChoices):
MINE_AAA = '1', 'a',
MINE_BBB = '2', 'b',
MINE_CCC = '3', 'c',
MINE_DDD = '4', 'd',
MINE_EEE = '5', 'e'
my_type = models.CharField(max_length=1, choices=MyTypes.choices)
TextChoices
是 python Enum
类型的扩展,其行为与您可能习惯的有点不同。
查询 my_type
时,您将得到一个字符串,因为它是 CharField
,这就是它在数据库中的存储方式。字符串值始终是 MyTypes
类中的选择之一,例如:
>>> MyModel.objects.create(my_type=MyModel.MyTypes.MINE_AAA)
<MyModel: MyModel object (1)>
>>> a = MyModel.objects.get(my_type=MyModel.MyTypes.MINE_AAA)
>>> a.my_type == MyModel.MyTypes.MINE_AAA
True
>>> type(a.my_type)
str
>>> type(MyModel.MyTypes.MINE_AAA)
<enum 'MyTypes'>
>>> type(MyModel.MyTypes.MINE_AAA.value)
str
我建议使用
TextChoices
来简洁、方便,最重要的是为了整个代码库的一致性。您应该始终远离静态检查选择字段。
如果使用 TextChoice
被证明太麻烦,您可以使用更传统的方式来声明保存选择的变量和 CHOICES
元组(如果您打算改变它,则为列表)
在这个例子中使用 CHOICES
元组看起来像这样
class MyModel(models.Model):
MINE_AAA = "1"
MINE_BBB = "2"
MINE_CCC = "3"
MINE_DDD = "4"
MINE_EEE = "5"
CHOIES = (
(MINE_AAA, "a"),
(MINE_BBB, "b"),
(MINE_CCC, "c"),
(MINE_DDD, "d"),
(MINE_EEE, "e"),
)
my_type = models.CharField(max_length = 1, choices=CHOICES)
您可以通过执行与之前几乎相同的操作来检查值,唯一的区别是实际变量本身也将是
str
:
>>> a = MyModel.objects.get(my_type=MyModel.MyTypes.MINE_AAA)
>>> a.my_type == MyModel.MINE_AAA
True
>>> type(MyModel.MINE_AAA)
str