繁体   English   中英

Django:django-tables2分页和过滤

[英]Django: django-tables2 pagination and filtering

我有一个由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 ,显示已过滤表的第二页

我希望过滤器在浏览不同页面时能够保持不变。 我在这里发现了类似的问题。 该解决方案表明需要更改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>

由于GET中不存在my_choice因此会导致my_choice 结果,页面甚至无法加载。

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

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

您是否还在使用GET或POST提交过滤器表单? 请确保使用GET提交!

最后,请看看我对这个问题的回答Django Tables-Column Filtering

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

更新2:您的视图的问题是,当您第一次访问该页面时, GET词典不包含my_choice属性,因此当尝试通过[]运算符访问my_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})

上面的方法应该可以工作,但是通过自己对查询集进行过滤- 您几乎违反了所有django设计原则

这就是为什么我告诉您阅读我对类似问题( Django Tables-Column Filtering )的其他答案的原因,在该问题中,我建议使用django-filter ,这是一个明确用于过滤查询集的软件包。 请检查文档或我的答案以查看其用法(如果您有任何疑问,我们将很乐意为您提供帮助)。

此外,您的代码还有许多其他小问题:

  • 你并不需要检查request.methodGET -它永远是GET ,因为你不会做任何POST小号

  • 您不应该在模板中包含{{ csrf_token }} -只有POST才需要。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM