Django:在第一页上以不同的方式分页 [英] Django: paginating differently on the first page

查看:11
本文介绍了Django:在第一页上以不同的方式分页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在使用 Django 的 object_list 来处理分页.如果您在听到我的问题后认为我需要它,我很高兴转到适当的 Paginator() 类:

At the minute, I'm using Django's object_list to handle pagination. I'm happy to move to the proper Paginator() class if you think I need it after you hear my problem:

在主页上,我想按 7 分页,但在所有其他页面上,我想按 10 分页.

On the homepage, I want to paginate by 7, but on all other pages I want to paginate by 10.

我该怎么做?我真的无法理解它.我最接近让它工作的结果是一整页结果被遗漏了,所以显然我不想要那样.

How would I go about doing this? I really can't get my head around it. The closest I've got to making it work resulted in a whole page of results being left out, so obviously I don't want that.

我会非常感激任何答案.如果您需要更多信息,请告诉我.非常感谢.

I'd be extremely appreciative of any answers. Let me know if you need any more information. Thanks a lot.

推荐答案

只需 from django.core.paginator import Paginator 并制作一个分页器对象 p = Paginator(thestuff, 7) 在主页视图中,p = Paginator(thestuff, 10) 其他地方.然后在任何一种情况下都在用于呈现模板的上下文中绑定 p.p.object_list 在任何一种情况下都会被适当地设置(并且您似乎是说这就是您正在使用的方法,对吗?即,这就是您所说的Django 的 object_list"?).

Just from django.core.paginator import Paginator and make a paginator object as p = Paginator(thestuff, 7) in the view for the homepage, p = Paginator(thestuff, 10) everywhere else. Then in either case bind p in the context you use to render the template. p.object_list will be set appropriately in either case (and you appear to say that's the approach you're using, right? I.e., is that what you mean by "Django's object_list"?).

Django docs 有很好的细节和例子(假设你是1.0 或更高版本).如果你不能让它工作,你能向我们展示(一个仍然失败的简化版本)你的模板和查看代码吗?

Django docs have excellent details and examples (assuming you're on 1.0 or better). If you can't make it work, can you show us (a simplified version that still fails, of) your template and view code?

问题现在已经清楚地显示出来,我认为应该通过继承Django的核心分页器来解决,如下:

problem has now been clearly shown and I think should be solved by subclassing Django's core paginator, as follows:

from django.core.paginator import Paginator, Page

class MyPaginator(Paginator):

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

  def page(self, number):
    "Returns a Page object for the given 1-based page 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)

现在完全按照上面的文本和示例使用 MyPaginator 来展示 Django 自己的用法,除了在创建它时,使用额外的命名参数 deltafirst=3 使第一页 3 比正常的每页长度(10).因此,您将使用标称长度为 10 但 deltafirst 为 3 的单个分页器,以使第一页 3 比所有其他页短.

Now use MyPaginator exactly as the above text and examples show the usage of Django's own, except, on creating it, use an extra named argument deltafirst=3 to make the first page 3 shorter than the normal per-page length (of 10). So you'd be using a single paginator with a nominal length of 10 but a deltafirst of 3 to make the first page 3 shorter than all others.

(validate_number 中可能存在问题,但我不确定它们是否会出现——如果它们出现,那么 MyPaginator 也需要覆盖该方法).

(There may be problems in validate_number but I'm not sure they'd appear -- if they do, then MyPaginator will need to override that method as well).

Django 最新版本的更新:

由于没有考虑位置参数,上面的代码会出错,并且还需要覆盖 num_pages 以允许正确显示最后一页:

The above code would give an error due to not accounting the positional arguments and num_pages also needs to be overriden to allow the last pages to be shown properly:

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 self._get_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)

这篇关于Django:在第一页上以不同的方式分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆