Django:django-tables2分页和过滤 [英] Django: django-tables2 pagination and filtering

查看:166
本文介绍了Django:django-tables2分页和过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由django-tables2生成的工作表:

I have a working table generated by 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个项目。当我单击表格底部的下一步时,分页效果很好,并且可以浏览不同的页面。但是,我注意到以下行为:

The above code returns a table with hundreds of objects that are neatly paginated with 10 items per page. When I click "Next" at the bottom of the table, pagination works well and I can navigate through different pages. However, I noticed the following behavior:


  • 单击 my_filter 会显示一个子集原始未过滤表

  • 单击已过滤表底部的下一步将显示未过滤表的第二页

  • 点击在 my_filter 上再次显示已过滤表的第二页

  • Click on my_filter which displays a subset of the original unfiltered table
  • Click "Next" on the bottom of the filtered table will result in displaying the 2nd page of the unfiltered table
  • Click on my_filter again displays the 2nd page of the filtered table

过滤器在浏览不同页面时仍然存在。我在此处找到了类似的问题。该解决方案表明需要更改html代码。但是,在我的情况下,django-tables2正在生成html。

I would like the filter to persist while navigating different pages. I found a similar question here. That solution indicates that the html code needs to be altered. However, in my case django-tables2 is generating the html.

如何正确地使用django-tables2进行分页过滤?

How can I correctly implement pagination with filtering using django-tables2?

-更新-

-Update-

我尝试使用GET而不是POST:

I've tried using GET instead of 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>

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

This results in a KeyError due to my_choice not existing in GET. As a result the page does not even load.

推荐答案

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

Which version of django_tables2 are you using? I checked the source and saw that django_tables2 is using a template tag named querystring for creating the pagination links in the table.html template. the querystring tag updates the current url with the paging parameters. so django_tables2 supports pagination + filtering out of the box (that's what I remembered).

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

Please try updating to the latest version of django_tables2 and make sure that you are using the default table.html template for rendering your tables.

还要使用GET或POST提交过滤器表单吗?请确保使用GET提交!

Also are you submitting your filter form with GET or POST? Please make sure that submit it with GET!

最后,请看一下我对这个问题的回答 Django表-列过滤

Finally, please take a look at my answer to this question Django Tables - Column Filtering

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

update: I took a closer look in the code you posted: first of all, you are passing post data to the filter: you cannot use POST for that, POST has to be used only for actions that modify your data. also I saw that you do not filter anything but instead you pass .all() to the table! where is the actual filtering done? you should pass the filtered data to the table as I describe in the answer above!

更新2:
您的问题看法是,当您第一次访问该页面时, GET 词典不包含 my_choice 属性,因此它将引发异常尝试通过 [] 运算符访问 my_choice 属性时,因此您应该使用以下命令检查它是否确实存在例如 .get(),像这样:

update 2: The problem with your view is that when you first visit the page the GET dictionary does not contain the my_choice attribute so it will throw an exception when trying to access the my_choice attribute through the [] operator, so you should check to see if it actually exists using for instance .get(), something like this:

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设计哲学

The above should work, however by doing do queryset filtering yourself - you are violating nearly every django design philosophy !

这就是我告诉你阅读的原因我对类似问题( Django表-列过滤)的其他答案,我建议使用< href = https://github.com/alex/django-filter rel = nofollow noreferrer> django-filter ,这是一个明确用于过滤查询集的软件包。请检查文档或我的答案以查看其用法(如果您有任何疑问,我们将很乐意为您提供帮助。)

That's why I told you to read my other answer to the similar question (Django Tables - Column Filtering) in which I recommend using django-filter which is a package explicitly used for filtering querysets. Please check the documentation or my answer to see how it can be used (I'd be happy to help if you have questions).

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

Also, there is a number of other minor problems with your code:


  • 您无需检查 request.method GET -它将始终是 GET ,因为您不会执行任何 POST s

  • You don't need to check if the request.method is GET - it will always be GET since you won't do any POSTs

您不应包含 {{csrf_token}} 到您的模板-仅在 POST 中需要。

You shouldn't include {{ csrf_token }} to your template - it is only needed for POST.

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

The TestFilter class is actually a Form that's why I recommend naming it TestFilterForm or something similar -- if you'd used django-filter then you'd create a FilterSet class which'd be named TestFilter. Correct naming of classes is very important, when I first saw your code I thought that the TestFilter class was a FilterSet and not a Form !

这篇关于Django:django-tables2分页和过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆