【问题标题】:different number of records in django pagination pagesdjango分页页面中不同数量的记录
【发布时间】:2021-03-26 17:21:54
【问题描述】:

我正在尝试在第一页 (5) 和所有其他页面(最多 6 个)上使用不同的内容进行分页以最大化元素。 我喜欢这个answer

class MyPaginator(Paginator):

    def __init__(self, **kw):
        self.deltafirst = kw.pop('deltafirst', 0)
        Paginator.__init__(self, **kw)

    def page(self, number):
        number = self.validate_number(number)
        if number == 1:
            bottom = 0
            top = self.per_page - self.deltafirst
        else:
            bottom = (number - 1) * self.per_page - self.deltafirst
            top = bottom + self.per_page
        if top + self.orphans >= self.count:
            top = self.count
        return Page(self.object_list[bottom:top], number, self)


from django.core.paginator import Paginator
from django.core.paginator import EmptyPage
from django.core.paginator import PageNotAnInteger

class NewsView(ListView):
    model = News
    template_name="mysite/news.html"
    paginate_by =  5

    def get_context_data(self, **kwargs):
        context = super(NewsView, self).get_context_data(**kwargs) 
        all_news = News.objects.all().order_by("-date_news")
        paginator = MyPaginator(all_news, self.paginate_by,deltafirst=1)

        page = self.request.GET.get('page')

        try:
            file_exams = paginator.page(page)
        except PageNotAnInteger:
            file_exams = paginator.page(1)
        except EmptyPage:
            file_exams = paginator.page(paginator.num_pages)
        context['all_news'] = file_exams
        return context

但我得到一个错误,我无法弄清楚我做错了什么。错误本身

    paginator = MyPaginator(all_news, self.paginate_by,deltafirst=1)
TypeError: __init__() takes 1 positional argument but 3 were given

【问题讨论】:

    标签: django


    【解决方案1】:

    首先更改MyPaginator中的__init__方法以修复错误:

    from math import ceil
    
    
    class MyPaginator(Paginator):
        
        def __init__(self, *args, **kw):
            self.deltafirst = kw.pop('deltafirst', 0)
            super().__init__(*args, **kw)
        
        def page(self, number):
            number = self.validate_number(number)
            if number == 1:
                bottom = 0
                top = self.per_page - self.deltafirst
            else:
                bottom = (number - 1) * self.per_page - self.deltafirst
                top = bottom + self.per_page
            if top + self.orphans >= self.count:
                top = self.count
            return Page(self.object_list[bottom:top], number, self)
    
        @property
        def num_pages(self):
            if self.count == 0 and not self.allow_empty_first_page:
                return 0
            count = max(self.count - self.per_page + self.deltafirst, 0)
            hits = max(0, count - self.orphans)
            return 1 + ceil(hits / self.per_page)
    

    接下来让您的视图更简单,而不是覆盖 get_context_data 覆盖 get_paginator 并将 deltafirst 设置为类属性:

    class NewsView(ListView):
        model = News
        template_name="mysite/news.html"
        paginate_by =  5
        paginator_class = MyPaginator
        deltafirst = 1
        
        def get_paginator(self, *args, **kwargs):
            if self.deltafirst:
                kwargs['deltafirst'] = self.deltafirst
            return super().get_paginator(*args, **kwargs)
    

    【讨论】:

    • 现在我有这个错误in get_paginator allow_empty_first_page=allow_empty_first_page, **kwargs) TypeError: __init__() takes 1 positional argument but 3 were given
    • @ВадимШаройкин 您是否更改了__init__ 方法的定义,就像我在答案中显示的def __init__(self, *args, **kw): 一样?注意添加*args,。还要保留类的其余代码,即page 方法。
    • 还有一个小问题。如果在 2 及以下页面上,剩余的元素少于 5 个,则不会显示它们?
    • @ВадимШаройкин 你是什么意思?如果某些页面的项目太少,您是否希望这些项目应该显示在最后一页?为此在您的ListView 中设置paginate_orphans = <number here>。如果您将其设置为 2 并且最后一页只有 2 个或更少的项目,它们将显示在上一页中,现在将是最后一页。
    • @ВадимШаройкин 我明白了,实际上链接的答案有点旧。我已经更新了我的答案并覆盖了num_pages 属性来解决这个问题。
    猜你喜欢
    • 2019-01-02
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 2011-11-15
    • 2020-12-05
    • 2013-09-12
    • 2012-03-14
    • 1970-01-01
    相关资源
    最近更新 更多