Django Pagination: переключение между нумерацией страниц или без ListView. - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь разработать умный способ переключения между разбитым на страницы шаблоном и не разбитым на страницы.

У меня уже есть работающий paginator, и я подумывал добавить рядом с ним кнопку с надписью «Показать все результаты», которая связана со списком без нумерации страниц, и тогда будет еще одна кнопка, чтобы вернуться к разбитому на страницы. список.

1) Простое решение

Используйте 2 ListViews с различными назначениями атрибута paginate_by (django по умолчанию устанавливает пагинацию), но, поскольку у меня много списков в моем проекте, это было бы не удобно (не слишком умно).

2) Решение Я застрял на

Напишите Mixin (который позже будет расширен моими ListViews), чтобы установить переменную paginate_by на основе условия, а затем добавить некоторые полезные переменные в контекст:

class PaginationMixin:
    no_pagination = False
    no_pagination_url = ''

    def get_paginate_by(self, queryset):
     # overwrite django method
        if self.no_pagination:
            return None
        else:
            return super().get_paginate_by(queryset)

    def get_no_pagination_url(self):
        return self.no_pagination_url

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['no_pagination'] = self.no_pagination
        context['no_pagination_url'] = self.get_no_pagination_url()
        return context

 class MyListView(PaginationMixin, ListView):
     #...
     def get_no_pagination_url(self):
         return reverse('mylist_urlname')

ПРОБЛЕМА: я не знаю, как установить переменную no_pagination из шаблона. Есть ли способ сделать это?

Спасибо за помощь.

ОБНОВЛЕННОЕ РЕШЕНИЕ (отредактировано из @ hi-lan solution): Таким образом, он покажет все результаты, а также сохранит URL-адреса (от фильтров или других), если они присутствуют.

class PaginationMixin:

    toggle_pagination = False
    toggle_pagination_url = ''
    no_pagination = False
    view_name = ''
    urlparams_dict = {}

    def get(self, request, page=None, *args, **kwargs):
        #store current GET params and pop 'page' key
        self.urlparams_dict = request.GET            
        self.urlparams_dict.pop('page', None)

        page = page or request.GET.get('page', '1')
        if page == 'all':
            page = self.paginate_by = None
            self.no_pagination = True
        return super().get(request, page=page, *args, **kwargs)

    def get_paginate_by(self, queryset):
        if self.no_pagination:
            return None
        else:
            return super().get_paginate_by(queryset)

    def get_toggle_pagination_url(self):
        # variables to set in view to toggle this mixin
        if self.toggle_pagination and self.view_name:
            if not self.no_pagination:
                extra = {'page': 'all'}
                self.urlparams_dict.update(extra)
            else:
                self.urlparams_dict.pop('page', None)
            # url keeps track of urlparams adds page=all if toggled
            self.toggle_pagination_url = reverse(self.view_name) + '?' + urlencode(self.urlparams_dict)
        return self.toggle_pagination_url

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['toggle_pagination_url'] = self.get_toggle_pagination_url()
        context['toggle_pagination'] = self.toggle_pagination
        return context

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Я пытаюсь ОБНОВЛЕННОЕ РЕШЕНИЕ gccallie с этим представлением:

class StageTempList(PaginationMixin, LoginRequiredMixin, SingleTableMixin, FilterView):
    view_name = 'stagetemp-list'
    table_class = StageTempTable
    model = StageTemp
    filterset_class = StageTempFilter
    template_name = 'stage/stagetemp_list.html'
    paginate_by = 30
    strict = False

Но когда get_paginate_by возвращает None, я получаю 25 строк. Джанго версия 2.1.2

ОБНОВЛЕНИЕ: PaginationMixin Class I используется

class PaginationMixin:
    no_pagination = False
    view_name = ''

    def get(self, request, page=None, *args, **kwargs):
        page = page or request.GET.get('page', '1')
        if page in ['0', 'all']:
            page = self.paginate_by = None
            self.no_pagination = True
        else: pass
        return super().get(request, page=page, *args, **kwargs)

    def get_paginate_by(self, queryset):
        # overwrite django method
        if self.no_pagination:
            return None
        else:
            return super().get_paginate_by(queryset)

    def get_no_pagination_url(self):
        extra = {'page': 'all'}
        no_pagination_url = reverse(self.view_name) + '?' + urlencode(extra)
        return no_pagination_url

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['no_pagination'] = self.no_pagination
        context['no_pagination_url'] = self.get_no_pagination_url()
        return context
0 голосов
/ 10 января 2019

Проблема в потоке данных от пользователя, чтобы указать, что нет нумерации страниц. Единственный способ, которым я могу придумать, - это использовать специальный номер страницы. Есть два варианта, в зависимости от того, как вы настраиваете urls.py.

  • В случае path('objects/page<int:page>/', PaginatedView.as_view()), специальный номер равен 0 (как обычный номер страницы начинается с 1).

  • В случае /objects/?page=3 специальное число может быть all.

В любом случае нам нужно переопределить метод get, поскольку именно там мы можем получить выбор пользователя.

class PaginationMixin:
    no_pagination = False
    view_name = ''

    def get(self, request, page=None, *args, **kwargs):
        page = page or request.GET.get('page', '1')
        if page in ['0', 'all']:
            page = self.paginate_by = None
        else: pass
        return super().get(request, page=page, *args, **kwargs)

    def get_paginate_by(self, queryset):
        # overwrite django method
        if self.no_pagination:
            return None
        else:
            return super().get_paginate_by(queryset)

    def get_no_pagination_url(self):
        # For using path
        extra = {'page': '0'}
        no_pagination_url = reverse(self.view_name, kwargs=extra)
        # For using query params
        extra = {'page': 'all'}
        no_pagination_url = reverse(self.view_name) + '?' + urlencode(extra)
        return no_pagination_url

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['no_pagination'] = self.no_pagination
        context['no_pagination_url'] = self.get_no_pagination_url()
        return context


class MyListView(PaginationMixin, ListView):
    view_name = 'mylist_urlname'
    #...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...