搜索NullBooleanField的表单

时间:2016-07-11 13:10:47

标签: django null django-forms

我为django模型编写了一个搜索表单,其中包含列is_ok作为NullBooleanField。

我想有4个选择:

  • 搜索此列为true的实例。
  • 搜索此列为false的实例。
  • 搜索此列为NULL的实例。
  • 在搜索
  • 中忽略此列

到目前为止,我使用它:

is_ok = forms.NullBooleanField(required=False)

但这只能呈现三个选项(如下拉列表)。

如何区分“is NULL”和“not set”?

1 个答案:

答案 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