首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django分页:在分页/非分页ListView之间切换

Django分页:在分页/非分页ListView之间切换
EN

Stack Overflow用户
提问于 2019-01-09 16:09:50
回答 2查看 1.1K关注 0票数 1

我正在详细阐述一种聪明的方法,在分页模板和非分页模板之间切换。

我已经有了一个工作分页器,我正在考虑在它旁边添加一个按钮,上面写着“显示所有结果”,该按钮链接到一个非分页列表,然后将有另一个按钮返回到分页列表。

1)简单解决方案

使用2 ListViews,使用属性paginate_by的不同分配(django默认设置分页),但是由于我的项目中有许多列表,这将不方便(也不太明智)。

2)解决方案我被困在上了

编写Mixin (稍后将由我的ListViews进行扩展),根据条件设置变量paginate_by,然后向上下文中添加一些有用的变量:

代码语言:javascript
复制
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 (来自过滤器或其他)。

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-10 02:40:57

问题在于从用户返回的数据流以指示非分页。我唯一能想到的方法就是使用特殊的页码。有两个选项,取决于您配置urls.py的方式。

  • path('objects/page<int:page>/', PaginatedView.as_view()),情况下,特殊编号为0(因为普通页码从1开始)。
  • /objects/?page=3的情况下,特殊号码可以是all

在这两种情况下,我们都需要覆盖get方法,因为它是检索用户选择的位置。

代码语言:javascript
复制
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'
    #...
票数 1
EN

Stack Overflow用户

发布于 2019-01-27 14:28:12

我正在尝试使用以下视图更新gccallie解决方案:

代码语言:javascript
复制
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行。Django版本2.1.2

更新:我使用的PaginationMixin类

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54114137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档