Django:Django-tables2分页和过滤

2024-09-29 23:27:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个由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>

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


Tags: djangogetobjectsrequestmyhtmltable页面
1条回答
网友
1楼 · 发布于 2024-09-29 23:27:56

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

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

同时,你是在提交带有GET或POST的过滤表单吗?请确保与GET一起提交!

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

更新:我仔细查看了您发布的代码:首先,您正在将post数据传递给筛选器:您不能为此使用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})

上面的方法应该是可行的,但是通过对自己进行do queryset过滤-你几乎违反了每一个django design philosophy

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

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

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

  • 您不应该将{{ csrf_token }}包含到您的模板中-它只用于POST

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

相关问题 更多 >

    热门问题