我正在摸索着这个。我的数据库中有一个枚举数据。我的模型有类似的东西:
class SomeModel(models.Model):
TWOCHOICE = (
('YES', 'YES'),
('NO', 'NO'),
('DK', 'Don't Know'),
)
myfield = models.IntegerField(max_length=1, choices=TWOCHOICE)
现在,当我想查询时,我不能使用:
SomeModel.objects.filter(myfield__in = ['YES', 'NO'])
看起来最直接。我必须使用整数值。所以我最终使用了:
SomeModel.objects.filter(myfield__in = [[t[0] for t in SomeModel.TWOCHOICE].index(i) for i in ['YES', 'NO']])
但这还不够。这些字段似乎从1开始索引!!!!所以我需要这样的东西:
SomeModel.objects.filter(myfield__in = [[t[0] for t in SomeModel.TWOCHOICE].index(i)+1 for i in ['YES', 'NO']])
我觉得这太复杂了。有没有更好的方法来查询Django中的枚举类型?
答案 0 :(得分:1)
对于可读性的选择字段,Django允许您指定两个值,第一个是要存储在DB中的实际值,第二个值将以表格形式显示,以便于阅读。例如在
中CHOICES = (
(0, 'No'),
(1, 'Yes'),
(2, 'Don\'t Know'),
)
将存储在数据库中的值为[0,1,2]
但是为了便于阅读,它们的关联字符串将以表格等形式显示。
就你的问题而言,这里的问题是你正在使用IntegerField
myfield
来尝试按字符串过滤。无论何时进行筛选查找(filter(...) or exclude(...)
),都必须提供与数据库中存储的内容相关的值。因此,无论何时要在IntegerField
上进行过滤,都必须提供一个用于过滤的整数。我不确定为什么Django允许你选择IntegerField
,其中第一个值不是整数,但你应该改变它。如果您将使用上述示例选项值,则可以按
yes
或no
.filter(myfield__in=[0,1])
如果要按关联的字符串值进行过滤,实际上没有简单的方法。您必须先查找与字符串相关的存储值。
def lookup_choices(choices, values):
choices = dict(choices)
rchoices = {choices [k]: k for k in choices}
return [rchoices[v] for v in values]
.filter(myfield__in=lookup_choices(CHOICES, ['Yes', 'No'])
你很少需要这样做,因为Django只会使用相关的字符串值来渲染值(选择框),但总会返回实际值(例如form.cleaned_data
)。