我有一个由django-tables2生成的工作表:
my_filter = TestFilter(request.POST)
table = TestTable(TestObj.objects.all(), order_by="-my_date")
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'test_app/index.html', {'table': table, 'my_filter': my_filter})
上面的代码返回一个包含数百个对象的表,这些对象整齐地分页,每页有10个项目。当我点击表格底部的“下一步”时,分页效果很好,我可以浏览不同的页面。但是,我注意到以下行为:
my_filter
my_filter
再次显示已过滤表格的第二页我希望过滤器在导航不同页面时保持不变。我发现了一个类似的问题here。该解决方案表明需要更改html代码。但是,在我的情况下,django-tables2正在生成html。
如何使用django-tables2?
正确实现过滤分页-Update -
我尝试过使用GET而不是POST:
if request.method == 'GET':
my_filter = TestFilter(request.GET)
my_choice = my_filter.data['my_choice']
table = TestTable(TestObj.objects.filter(choice=my_choice), order_by="-my_date")
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'test_app/index.html', {'table': table, 'my_filter': my_filter})
我的模板:
<form action="" method="get"> {% csrf_token %}
{{ my_filter }} <input type="submit" value="Apply Filter"/>
</form>
由于GET中不存在my_choice
,导致KeyError。因此,页面甚至无法加载。
答案 0 :(得分:6)
您使用的是哪个版本的django_tables2?我检查了源代码,发现django_tables2正在使用名为querystring
的模板标记来创建table.html
模板中的分页链接。 querystring
标记使用分页参数更新当前网址。所以django_tables2支持分页+过滤开箱即用(这就是我所记得的)。
请尝试更新到最新版本的django_tables2,并确保使用默认的table.html
模板来呈现您的表格。
您是也使用GET或POST提交过滤表单?请确保通过GET提交!
最后,请查看我对此问题的回答Django Tables - Column Filtering
更新:我仔细查看了您发布的代码:首先,您将帖子数据传递给过滤器:您不能使用POST,POST必须仅用于修改数据的操作。我也看到你没有过滤任何东西,而是将.all()传递给桌子!实际过滤在哪里完成?您应该将过滤后的数据传递给表格,正如我在上面的答案中所描述的那样!
更新2:
您的视图的问题是,当您第一次访问该页面时,GET
字典不包含my_choice
属性,因此在尝试通过{访问my_choice
属性时会抛出异常{1}}运算符,因此您应该使用例如[]
检查它是否确实存在,如下所示:
.get()
上面应该可行,但是你自己做了一个查询集过滤 - 几乎每个django design philosophy都违反了你的行为!
这就是为什么我告诉你读我对类似问题(Django Tables - Column Filtering)的另一个答案,其中我建议使用django-filter这是一个明确用于过滤查询集的包。请查看文档或我的答案,看看它是如何使用的(如果您有任何疑问,我很乐意提供帮助)。
此外,您的代码还存在许多其他小问题:
您无需检查my_filter = TestFilter(request.GET)
my_choice = my_filter.data.get('my_choice') # This won't throw an exception
if my_choice: # If my_choice existed on the GET dictionary this will return non-null value
table = TestTable(TestObj.objects.filter(choice=my_choice), order_by="-my_date")
else:
table = TestTable(TestObj.objects.all(), order_by="-my_date")
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'test_app/index.html', {'table': table, 'my_filter': my_filter})
是否为request.method
- 它始终为GET
,因为您不会GET
< / p>
您不应该在模板中加入POST
- {{ csrf_token }}
只需要{。}}。
POST
类实际上是TestFilter
,这就是为什么我建议将其命名为Form
或类似的东西 - 如果你使用了django-filter那么你就创建了TestFilterForm
类,其名称为FilterSet
。正确命名类是非常重要的,当我第一次看到你的代码时,我认为TestFilter
类 是TestFilter
而不是FilterSet
!