我为django模型编写了一个搜索表单,其中包含列is_ok
作为NullBooleanField。
我想有4个选择:
到目前为止,我使用它:
is_ok = forms.NullBooleanField(required=False)
但这只能呈现三个选项(如下拉列表)。
如何区分“is NULL”和“not set”?
答案 0 :(得分:1)
正如@Alasdair所说,你必须创建一个自定义字段:
class UnsetType:
def __str__(self):
return '__unset__'
Unset = UnsetType()
class UnsetOrNullBooleanSelect(NullBooleanSelect):
def __init__(self, attrs=None):
choices = (
('__unset__', ugettext_lazy('Unset')),
('1', ugettext_lazy('Unknown')),
('2', ugettext_lazy('Yes')),
('3', ugettext_lazy('No')),
)
super().__init__(attrs, choices)
def render(self, name, value, attrs=None):
try:
value = {
True: '2', False: '3', None: '1',
'2': '2', '3': '3', '1': '1',
}[value]
except KeyError:
value = '__unset__'
return super().render(name, value, attrs)
def value_from_datadict(self, data, files, name):
value = data.get(name)
return {
'1': None, None: None, 'None': None, 'none': None, 'null': None,
'2': True, True: True, 'True': True,
'3': False, 'False': False, False: False,
}.get(value, Unset)
class UnsetOrNullBooleanField(NullBooleanField):
widget = UnsetOrNullBooleanSelect
def to_python(self, value):
if value in (True, 'True', 'true', '1'):
return True
elif value in (False, 'False', 'false', '0'):
return False
elif value in (None, 'None', 'none', 'null'):
return None
else:
return Unset