Я пытаюсь разработать умный способ переключения между разбитым на страницы шаблоном и не разбитым на страницы.
У меня уже есть работающий 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