Разбиение на страницы с использованием ListView и динамического/фильтрованного набора запросов

У меня есть представление на основе классов, которое я использую для отображения набора запросов в таблице. Я также использую пару наборов форм для фильтрации этого набора запросов. Я использую метод get_queryset(), предоставленный как часть класса generic.ListView, для фильтрации отображаемых результатов. Вот как выглядит мой класс:

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 отбрасывается, и страница действует так, как будто я перехожу на страницу № 2 из MyModel.objects.all() вместо моего отфильтрованного подмножества.

Как сохранить отфильтрованный набор запросов при использовании элементов управления нумерацией страниц?

Вот 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 %}

comment
Часто поиск выполняется через GET по двум причинам: (а) параметры могут быть легко переданы на следующую страницу, и (б) поскольку запрос закодирован, вы можете поделиться URL-адресом с другим пользователем, который затем также получит результаты поиска. .   -  person Willem Van Onsem    schedule 24.08.2018
comment
Есть и семантическая причина; GET означает получение информации с сервера в соответствии с этими параметрами, тогда как POST означает внесение изменений на сервере с использованием этих значений, чего вы не делаете.   -  person Daniel Roseman    schedule 24.08.2018
comment
Это имеет смысл. Я провел некоторое тестирование и попытаюсь переключиться на GET. Если это плохо работает, закройте это.   -  person Rosey    schedule 24.08.2018


Ответы (1)


Переключение на запрос 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>
person Rosey    schedule 24.08.2018