Django нумерация страниц - поддержание фильтра и порядок по - PullRequest
0 голосов
/ 29 января 2020

У меня небольшой Django проект basi c -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 и, таким образом, потерять отфильтрованный набор запросов, который я хотел.

Как сохранить фильтрацию в процессе разбивки на страницы?

Ответы [ 2 ]

1 голос
/ 29 января 2020

Как указал @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 - это 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

Не самое элегантное решение, но я считаю, что большинству людей его достаточно просто использовать.

0 голосов
/ 29 января 2020

У меня была такая же проблема, и я решил ее по ссылке ниже.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...