目前,我正在使用 Django 的 object_list 来处理分页。如果您在听到我的问题后认为我需要它,我很高兴转到正确的 Paginator() 类:
在主页上,我想分页7,但在所有其他页面上,我想分页10。
我该怎么做呢?我真的无法理解它。我最接近让它工作的结果导致一整页的结果被遗漏了,所以显然我不希望这样。
我会非常感谢任何答案。如果您需要更多信息,请告诉我。非常感谢。
乔
目前,我正在使用 Django 的 object_list 来处理分页。如果您在听到我的问题后认为我需要它,我很高兴转到正确的 Paginator() 类:
在主页上,我想分页7,但在所有其他页面上,我想分页10。
我该怎么做呢?我真的无法理解它。我最接近让它工作的结果导致一整页的结果被遗漏了,所以显然我不希望这样。
我会非常感谢任何答案。如果您需要更多信息,请告诉我。非常感谢。
乔
就像在主页视图中一样,在其他任何地方from django.core.paginator import Paginator
创建一个分页器对象。然后在任何一种情况下,在您用来呈现模板的上下文中绑定。在任何一种情况下都会被适当地设置(你似乎说这是你正在使用的方法,对吧?也就是说,这就是你所说的“Django's object_list”的意思吗?)。p = Paginator(thestuff, 7)
p = Paginator(thestuff, 10)
p
p.object_list
Django文档有很好的细节和示例(假设您使用的是 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 比所有其他页面短。
(可能存在问题,validate_number
但我不确定它们是否会出现——如果出现了,那么 MyPaginator 也需要覆盖该方法)。
最新版本的 Django 更新:
由于没有考虑位置参数,上面的代码会出错,并且num_pages
还需要重写以允许正确显示最后一页:
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)
object_list() 函数使用分页器来拆分列表。所以,如果你改变块的“大小”(7 对 8)......那么它会做你所看到的。
选择: 最后一个选择是靠不住的。不要那样做 :-) 要么“破解”它,要么转移到 Paginator。
破解它......在请求>第1页上,将一些额外的东西偷偷溜进row_list。我猜你可以通过list(row_list)强制它进入一个列表,并通过row_list.insert(0, None)在前面添加一个 None 或其他东西
分页...使用分页器
查看 + 模板...让您的视图只需将查询集 row_list 传递给模板。对第 1 页进行模板检查。您是否拥有 row_list 子集的循环/显示。在你的模板中有这样的逻辑是很糟糕的。它构成了一个复杂的模板。
我意识到这是一个老问题,但万一有人像我一样来到这里发现我的单元测试发现了一个问题。
亚历克斯基本上是正确的,但不要忘记也实施_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])
对于我的特定场景,我希望在 1 个渲染模板中对对象进行分页(创建一个多页文档)。就我而言,我认为最简单的方法是忘记分页器并改用生成器。
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 的函数,因此您确实拥有最大的灵活性。
在您的模板中,您可以像处理分页器一样处理它:
{% for page in pages %}
{% if page.number == 1 %}
{{ header }}
{% endif %}
{% for obj in page.object_list %}
{{ obj }}
{% endfor %}
{% endfor %}