为了账号安全,请及时绑定邮箱和手机立即绑定

Django 分页——维护过滤器和排序方式

Django 分页——维护过滤器和排序方式

慕工程0101907 2022-07-12 10:22:22
我有一个小型 Django 项目basic-pagination。有一个模型、一个表单和两个视图(列表视图、表单视图)。用户在表单视图中提交数据,然后数据显示在列表视图中。启用分页以一次仅显示 5 个帖子。我实现的是一个带有 GET 响应的表单,用于获取我想要显示的数据(例如姓名、日期)。请参阅下面的代码class FormListView(ListView):    model = models.ToDoList    paginate_by = 5  # if pagination is desired    template_name = 'pagination/listview.html'    context_object_name = 'forms'    def get_context_data(self, **kwargs):        context = super().get_context_data(**kwargs)        context['title'] = 'Form List View'        context['filter_form'] = forms.FilterListView(self.request.GET)        return context    def get_queryset(self):        queryset = models.ToDoList.objects.all().order_by('-id')        name = self.request.GET.get('name')        if name:            queryset = queryset.filter(name=name)        order_by = self.request.GET.get('order_by')        if order_by:            queryset = queryset.order_by(order_by)        print(queryset)        return queryset问题是,如果您从一个页面移动到另一个页面,那么基于类的视图会调用该方法ListView,从而丢失了我想要的过滤查询集。get_queryset12如何在整个分页过程中保持过滤?
查看完整描述

2 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

正如@WillemVanOnsem 指出的那样,问题不在于视图,而在于模板中的 URL(templates/pagination/listview.html)。以前,下一个按钮href="?page={{ page_obj.next_page_number }}"意味着request.GET它只包含用于分页的页码,而不包含其他过滤器和按条件排序。


然后解决方案是附加request.GET.urlencode到href喜欢


<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}&{{ request.GET.urlencode }}">Next</a>

但是,这不是一个彻底的解决方案,因为简单地附加request.GET也会附加您当前所在的页码。简单地说,如果你从第 1 页跳转到第 2 页再到第 3 页,你最终会得到一个看起来像这样的 URL


http://localhost:8000/listview/?page=1&page=2&page=3...

这request.GET是一个 QueryDict 之类的<QueryDict: {'page': ['1'], ...}>。对此的解决方案是简单地弹出page参数,但是,因为request.GET它是不可变的,您首先必须制作它的副本。本质上,我get_context_data在 ListVew 中的方法中添加了以下几行


def get_context_data(self, **kwargs):

    context = super().get_context_data(**kwargs)

    context['title'] = 'Form List View'

    context['filter_form'] = forms.FilterListView(self.request.GET)

    get_copy = self.request.GET.copy()

    if get_copy.get('page'):

        get_copy.pop('page')

    context['get_copy'] = get_copy

    return context

在模板中,我将get_copy对象称为href="?page={{ page_obj.next_page_number }}&{{ get_copy.urlencode }}"


对于整个模板示例,请遵循templates/pagination/listview.html


不是最优雅的解决方案,但我觉得它对大多数人来说足够简单。


查看完整回答
反对 回复 2022-07-12
?
慕哥9229398

TA贡献1877条经验 获得超6个赞

我遇到了同样的问题,我通过下面的链接解决了这个问题。

https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/


查看完整回答
反对 回复 2022-07-12
  • 2 回答
  • 0 关注
  • 217 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号