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

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


如何在整个分页过程中保持过滤?


慕工程0101907
浏览 218回答 2
2回答

蝴蝶不菲

正如@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 页,你最终会得到一个看起来像这样的 URLhttp://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):&nbsp; &nbsp; context = super().get_context_data(**kwargs)&nbsp; &nbsp; context['title'] = 'Form List View'&nbsp; &nbsp; context['filter_form'] = forms.FilterListView(self.request.GET)&nbsp; &nbsp; get_copy = self.request.GET.copy()&nbsp; &nbsp; if get_copy.get('page'):&nbsp; &nbsp; &nbsp; &nbsp; get_copy.pop('page')&nbsp; &nbsp; context['get_copy'] = get_copy&nbsp; &nbsp; return context在模板中,我将get_copy对象称为href="?page={{ page_obj.next_page_number }}&{{ get_copy.urlencode }}"对于整个模板示例,请遵循templates/pagination/listview.html不是最优雅的解决方案,但我觉得它对大多数人来说足够简单。

慕哥9229398

我遇到了同样的问题,我通过下面的链接解决了这个问题。https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python