使用 ListView 和 dynamic/filtered 查询集进行分页

Pagination using ListView and a dynamic/filtered queryset

我有一个基于 class 的视图,用于在 table 中显示查询集。我还使用了几个表单集来过滤这个查询集。我正在使用作为 generic.ListView class 的一部分提供的 get_queryset() 方法来过滤显示的结果。这基本上是我的 class 的样子:

from django.views import generic

class UnifiedSingleSearch(generic.ListView):
    template_name = 'app/foo.html'
    model = MyModel
    paginate_by = 30

    def get_queryset(self):
        if self.request.POST:  # If we got here because of a search submission, filter
            return MyModel.objects.filter('Some stuff base on the POST data')
        return MyModel.objects.all()  # Otherwise, just show everything

因为我使用表单集来提交多个搜索条件,所以我必须使用 POST 请求。初次提交表单后,页面会重新加载正确过滤的查询集。但是,当我尝试使用我的分页控件时,POST 请求被丢弃,页面就像我要转到 MyModel.objects.all() 的第 2 页而不是我过滤掉的子集一样。

如何在使用分页控件时保留过滤后的查询集?

这是分页控件的 HTML:

{% if is_paginated %}
        <nav aria-label="Pagination nav">
            <ul class="pagination">
                {# Back a page #}
                {% if page_obj.has_previous %}
                    <li class="page-item">
                        <a class="page-link" href="?page={{ page_obj.previous_page_number }}">&#10094;</a>
                    </li>
                {% else %}
                    <li class="page-item disabled">
                        <span class="page-link">&#10094;</span>
                    </li>
                {% endif %}
                {# Page numbers #}
                {% for i in paginator.page_range %}
                    {% if page_obj.number == i %}
                        <li class="page-item active">
                            <span class="page-link">{{ i }}
                                <span class="sr-only">(current)</span>
                            </span>
                        </li>
                    {% else %}
                        <li class="page-item">
                            <a class="page-link" href="?page={{ i }}">{{ i }}</a>
                        </li>
                    {% endif %}
                {% endfor %}
                {# Next page #}
                {% if page_obj.has_next %}
                    <li class="page-item">
                        <a class="page-link" href="?page={{ page_obj.next_page_number }}">&#10095;</a>
                    </li>
                {% else %}
                    <li class="page-item disabled">
                        <span class="page-link">&#10095;</span>
                    </li>
                {% endif %}
            </ul>
        </nav>
    {% endif %}
{% else %}
    <p>No MyModel objects found</p>
{% endif %}

答案是切换到 GET 请求。分页控件也必须进行一些编辑以保留传递的查询字符串。它们都应该包括 {{ request.GET.urlencode }} 然后你像往常一样将页面逻辑添加到最后。最终看起来像这样:

<li class="page-item">
    <a class="page-link" href="?{{ request.GET.urlencode }}&page={{ page_obj.next_page_number }}">&#10095;</a>
</li>