gpt4 book ai didi

python - Django分页: switch between paginated/non-paginated ListView

转载 作者:行者123 更新时间:2023-12-01 08:27:46 37 4
gpt4 key购买 nike

我正在尝试详细阐述一种在分页模板和非分页模板之间切换的智能方法。

我已经有一个可用的分页器,我正在考虑在它旁边添加一个按钮,上面写着“显示所有结果”,链接到非分页列表,然后从那里会有另一个按钮返回到分页列表列表。

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解决方案编辑):这样它将显示所有结果,并保留 urlparams(来自过滤器或其他)(如果存在)。

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

最佳答案

问题在于从用户返回的数据指示非分页。我能想到的唯一方法是使用特殊页码。有两个选项,具体取决于您配置 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'
#...

关于python - Django分页: switch between paginated/non-paginated ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54114137/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com