Python Django:Django-tables2分页和筛选

Python Django:Django-tables2分页和筛选,python,django,django-tables2,Python,Django,Django Tables2,我有一个由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':

我有一个由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
    ,其中显示原始未筛选表的子集
  • 单击筛选表底部的“下一步”将显示未筛选表的第2页
  • 再次单击my_filter(我的过滤器),显示过滤表的第2页
我希望在浏览不同的页面时保持过滤器。我发现了一个类似的问题。该解决方案表明html代码需要修改。然而,在我的例子中,django-tables2正在生成html

如何使用django-tables2通过过滤正确实现分页

-更新-

我尝试使用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>
{%csrf\u令牌%}
{{my_filter}}

由于GET中不存在
my_choice
,因此这会导致键错误。因此,页面甚至无法加载。

您使用的是哪个版本的django_表2?我检查了源代码,发现django_tables2正在使用名为
querystring
的模板标记在
table.html
模板中创建分页链接。
querystring
标记使用分页参数更新当前url。所以django_表2支持分页+开箱即用过滤(这就是我记得的)

请尝试更新到django_tables2的最新版本,并确保使用默认的
table.html
模板呈现表格

您是否也在使用GET或POST提交筛选表单?请确保使用GET提交

最后,请看我对这个问题的回答

更新:我仔细查看了您发布的代码:首先,您正在将post数据传递给筛选器:您不能使用post,post只能用于修改数据的操作。我还看到,您不过滤任何内容,而是将.all()传递到表中!实际过滤在哪里完成?您应该将过滤后的数据传递到表中,正如我在上面的回答中所描述的那样

更新2: 您的视图存在的问题是,当您第一次访问页面时,
GET
字典不包含
my\u choice
属性,因此当试图通过
[]
操作符访问
my\u choice
属性时,它将引发异常,因此,您应该使用例如
.get()
,检查它是否确实存在,类似于以下内容:

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})
但是,通过自己进行do queryset筛选,您几乎违反了所有规则

这就是为什么我告诉您阅读我对类似问题()的另一个答案,在这个问题中,我建议使用which,它是一个显式用于过滤查询集的包。请检查文档或我的答案,看看如何使用它(如果您有问题,我很乐意提供帮助)

此外,您的代码还存在一些其他小问题:

  • 您不需要检查
    请求。方法是否为
    GET
    -它将始终为
    GET
    ,因为您不会执行任何
    POST
    s操作

  • 您不应该将
    {{csrf\u token}}
    包含到模板中-它仅用于
    POST

  • TestFilter
    类实际上是一个
    表单
    ,这就是为什么我建议将其命名为
    TestFilter
    或类似的名称——如果您使用了django过滤器,那么您将创建一个名为
    TestFilter
    FilterSet
    类。类的正确命名非常重要,当我第一次看到您的代码时,我认为
    TestFilter
    类是
    FilterSet
    而不是
    表单


我正在使用最新的django-tables2(0.14.0)。我已经用GET和POST进行了测试。我现在已经禁用了分页:(我已经用我的GET/POST测试的详细信息更新了问题。你能指出我做错了什么吗?请查看更新2,了解解决问题的方法和一些一般性建议!这为我解决了问题。感谢你的全面回答。非常感谢:)绝对正确。我还是一个学习的婴儿,总是从学者那里吸取建议。