所以我尝试在表单中使用带有空标签的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()
答案 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))