我正在使用django_tables2
因此部分代码依赖于此包,但这应该与整体问题无关。
forms.py
class PersonForm(forms.Form):
date_from = forms.DateField(input_formats='%d/%m/%Y')
date_to = forms.DateField(input_formats='%d/%m/%Y')
views.py
def filter(request):
table = PersonTable(Person.objects.all())
if request.method == 'POST':
form = PersonForm(request.POST)
if form.is_valid():
date_from = form.cleaned_data['date_from']
date_to = form.cleaned_data['date_to']
result_filtered = table.filter(date__range=(date_from, date_to))
RequestConfig(request, paginate={"per_page": 100}).configure(table)
return render(request, "people.html", {
"table": result_filtered })
args = {}
args.update(csrf(request))
args['form'] = PersonForm()
args['table'] = table
RequestConfig(request, paginate={"per_page": 100}).configure(table)
return render(request, 'people.html', args)
简单地说,过滤不起作用。我可以看到整个表格,但是当我尝试过滤时没有任何反应。你能看出什么是错的吗?
答案 0 :(得分:2)
我很确定你需要在查询集而不是表上调用.filter()
。例如:
result_filtered = PersonTable(Person.objects.filter(date__range=(date_from, date_to))
另外,在这一行:
RequestConfig(request, paginate={"per_page": 100}).configure(table)
你正在传递table
。您应该传递result_filtered
。
答案 1 :(得分:1)
这是我执行此操作的一种方式,假设您的Person
模型具有date
字段:
def filter(request):
if 'date_from' in request.GET and 'date_to' in request.GET:
# form data has been submitted
form = PersonForm(request.GET)
if form.is_valid():
date_from = form.cleaned_data['date_from']
date_to = form.cleaned_data['date_to']
people = Person.objects.filter(date__range=(date_from, date_to))
table = PersonTable(people)
else:
table = PersonTable(Person.objects.all())
else:
form = PersonForm()
table = PersonTable(Person.objects.all())
RequestConfig(request, paginate={"per_page": 100}).configure(table)
args = {}
args.update(csrf(request))
args['form'] = form
args['table'] = table
return render(request, 'people.html', args)
如果两个预期字段都存在,则绑定表单,并根据结果限制查询集(如果有效)。如果无效,则呈现绑定表单和从无限制表构建的表。如果未提交表单数据,则会呈现从无限制表构建的表。
如果使用此设计,您的表单标记的method
属性应为GET
而不是POST
。
这并不完全遵循用于表单处理的常用Django模式,因为表单实际上没有进行任何更改,因此您可以使用GET
并且不需要在成功时返回重定向。