【问题标题】:Django pagination -- maintaining filter and order byDjango 分页——维护过滤器和排序方式
【发布时间】:2020-01-29 17:38:34
【问题描述】:

我有一个小型 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_queryset 如果您从页面1 移动到页面2 并因此丢失了我想要的过滤查询集。

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

【问题讨论】:

  • 这与视图无关:您在模板中编写的 URL 不使用查询中的其他参数,而仅使用 page 参数。
  • @WillemVanOnsem 你有解决这个问题的建议吗?
  • 你有没有看到这个 SO post 看起来像是在处理一个相关的话题?
  • @Chris 我想我找到了解决办法。我为每个链接更改了href。例如href="?page={{ page_obj.next_page_number }}" --> href="?page={{ page_obj.next_page_number }}&{{ request.GET.urlencode }}"

标签: python django django-forms django-views


【解决方案1】:

正如@WillemVanOnsem 所指出的,问题不在于视图,而在于模板中的 URL(templates/pagination/listview.html)。以前,next 按钮具有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 是一个类似于&lt;QueryDict: {'page': ['1'], ...}&gt; 的QueryDict。对此的解决方案是简单地弹出page 参数,但是,因为request.GET 是不可变的,您首先必须复制它。本质上,我在 ListVew 中的 get_context_data 方法中添加了以下几行

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 }}&amp;{{ get_copy.urlencode }}"

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

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

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,我用下面的链接解决了。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 2019-08-14
      • 2019-11-06
      • 2013-02-19
      相关资源
      最近更新 更多