Django使用ValueListQuery Set为Choice字段添加一个空标签给Choice字段

时间:2015-02-04 20:03:40

标签: python django

所以我尝试在表单中使用带有空标签的ValueListQuerySet来过滤页面上显示的结果。我使用EmptyChoiceField code取得了成功(此代码也在下面的代码中粘贴),但是当我尝试将选项移动到init时,如this SO question所示,以便选择刷新每次表单加载时我都会丢失空值(请参阅下面代码中的注释)。

class EmptyChoiceField(forms.ChoiceField):
    def __init__(self, choices=(), empty_label=None, required=True, widget=None, label=None, initial=None, help_text=None, *args, **kwargs):

        # prepend an empty label if it exists (and field is not required!)
        if not required and empty_label is not None:
            choices = tuple([(u'', empty_label)] + list(choices))
        super(EmptyChoiceField, self).__init__(choices=choices, required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) 


class FilterForm(forms.Form):
    # The next line has the empty label but the list won't get updated when the form loads
    x = EmptyChoiceField(choices=Stuff.objects.all().values_list("x", "x").distinct(), required=False, empty_label="Show All")
    # The values get updated in the next line, but the empty_label stops working
    y = EmptyChoiceField(choices=[], required=False, empty_label="Show All")

    def __init__(self, *args, **kwargs):
        super(FilterForm, self).__init__(*args, **kwargs)
        self.fields['y'].choices= Stuff.objects.all().values_list("y", "y").distinct()

1 个答案:

答案 0 :(得分:1)

这是因为super(FilterForm, self).__init__(*args, **kwargs)将调用EmptyChoiceField.__init__方法,然后您在超级调用之后立即覆盖选项,以便覆盖EmptyChoiceField设置的选项。

有几种方法可以解决这个问题,我不确定哪一种方法最好,但最简单的方法是在FilterForm.__init__中执行以下操作:

def __init__(self, *args, **kwargs):
    super(FilterForm, self).__init__(*args, **kwargs)
    choices = Stuff.objects.all().values_list("y", "y").distinct()
    self.fields['y'].choices = tuple([(u'', empty_label)] + list(choices))