Django:第一页上的分页不同

时间:2009-06-28 14:04:16

标签: django pagination

当下,我正在使用Django的object_list来处理分页。如果您在听到我的问题后认为我需要它,我很高兴转到正确的Paginator()课程:

在首页上,我想通过 7 进行分页,但是在所有其他页面上我希望通过 10 进行分页。

我该怎么做呢?我真的无法理解它。我最接近它的工作导致整页结果被遗漏,显然我不希望这样。

我非常感谢任何答案。如果您需要更多信息,请与我们联系。非常感谢。

4 个答案:

答案 0 :(得分:6)

只需from django.core.paginator import Paginator并在主页视图{@ 1}}中将分页符对象设为p = Paginator(thestuff, 7),其他地方为p = Paginator(thestuff, 10)。然后在任何一种情况下,在用于呈现模板的上下文中绑定p。在任何一种情况下都会适当地设置p.object_list(你似乎说这是你正在使用的方法,对吗?就是说,你的意思是“Django的object_list”?)。

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

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

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比其他页短3。

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

答案 1 :(得分:1)

object_list()函数使用Paginator拆分列表。 所以,如果你改变了块的“大小”(7对8)......那么它就是你所看到的。

<强>选择 最后的选择是不可靠的。不要这样做:-)要么“破解它”要么转移到Paginator。

黑客攻击 ...请求&gt;第1页,偷偷进入row_list。我猜你可以通过 list(row_list)强制它进入列表,并通过 row_list.insert(0,无)

添加一个None或者其他内容

Paginate ...使用Paginator

查看+模板 ...让您的视图将查询集row_list传递给模板。让模板检查第1页。你是否拥有row_list子集的循环/显示。在你的模板中有这样的逻辑很糟糕。它构成了一个复杂的模板。

答案 2 :(得分:0)

我意识到这是一个老问题,但是如果有人像我一样来到这里发现我的单位测试发现了一个问题。

Alex基本上是正确的,但不要忘记同时使用_get_num_pages实施self.orphans + self.deltafirst,否则最后一页将不正确。

def _get_num_pages(self):
    """Returns the total number of pages."""
    if self._num_pages is None:
        if self.count == 0 and not self.allow_empty_first_page:
            self._num_pages = 0
        else:
            hits = max(1, self.count - self.orphans + self.deltafirst)
            self._num_pages = int(ceil(hits / float(self.per_page)))
    return self._num_pages
num_pages = property(_get_num_pages)

单位测试:

def test_ads_paginator(self):
    per_page = 10
    num_items = 100
    num_firstpage = 5
    expected_num_pages = 11

    items = range(num_items)
    paginator = AdsPaginator(items, per_page, deltafirst=per_page-num_firstpage)
    last_item = paginator.page(paginator.num_pages).object_list[-1]

    self.assertEqual(len(paginator.page(1)), num_firstpage)
    self.assertEqual(paginator.num_pages, expected_num_pages)
    self.assertEqual(last_item, items[-1])

答案 3 :(得分:0)

对于我的特定场景,我希望在1个渲染模板中对对象进行分页(创建多页文档)。对于我的情况,我认为最简单的方法是忘记paginator并使用生成器代替。

    def pages_iter():
        page_num = 1
        num_records = lambda x: 30 if x > 1 else 10
        end_idx = 0

        while True:
            start_idx = end_idx
            end_idx += num_records(page_num)
            yield {
                'number': page_num,
                'object_list': donors[start_idx:end_idx]
            }

            if end_idx > donors.count() - 2:
                break
            page_num += 1

{ pages: page_iter }添加到您的网页上下文中,然后您自己拥有一个变量分页器。请注意,num_records是一个采用page_number的函数,因此您确实具有最大的灵活性。

在你的模板中,你可以像对待paginator一样对待它:

{% for page in pages %}
  {% if page.number == 1 %}
    {{ header }}
  {% endif %}

  {% for obj in page.object_list %}
    {{ obj }}
  {% endfor %}
{% endfor %}