过滤表单设计

时间:2013-04-28 22:38:29

标签: python django django-forms

假设我有一个博客,我希望按类别或日期过滤条目:对于过滤器,我使用以下表格

#forms.py

class MyForm(forms.Form):
    categories = forms.ModelMultipleChoiceField(Category.objects.all(),
                                                required=False)
    start_date = forms.DateField(required=False)
    end_date = forms.DateField(required=False)

我有以下观点:

#views.py

blog_entries = Blog.objects.all()
cat_filter = TurnoverFilterForm(request.GET)
    if cat_filter.is_valid():
        categories_chosen = cat_filter.cleaned_data['categories']
        start_date = cat_filter.cleaned_data['start_date']
        end_date = cat_filter.cleaned_data['end_date']
        blog_entries = blog_entries.cat_filter(categories_chosen).date_filter(start_date,end_date)
return render(request,'index.html',{'blog_entries':blog_entries}

date_filtercat_filter是自定义管理器功能(可以工作)。

问题是:

  1. 我真的需要让表格中的每个字段都可选吗?那些案件有可选的表格吗? (因为有很多代码冗余)
  2. 我的表单中有一个丑陋的if语句,因为表单始终有效(或者至少应该是类别和日期范围是可选的,表单的请求类型是'get'
  3. 对于这类问题,还有其他优雅的解决方案吗?我可以想象它真的很常见

1 个答案:

答案 0 :(得分:2)

如果您希望表单中的所有字段都是可选字段,则可以覆盖表单的__init__函数,如下所示:

def __init__(self, *args, **kwargs):
    super(forms.Form, self).__init__(*args, **kwargs)
    for f in self.fields:
        self.fields[f].required=False

这样你就可以设置所有字段'必填字段为False并避免代码冗余以使整个表单成为可选字段。

类似is_valid方法会返回True,您可以将其从代码中删除,并将另一个函数添加到表单中,该函数将剩余代码封装在views.py中。

有了这个,您可以简化一点代码。如果你想让更高级的人想到Form类的子类并创建OptionalForm,那么你可以使代码重用。