Django分页和“当前页面”
Posted
技术标签:
【中文标题】Django分页和“当前页面”【英文标题】:Django pagination and "current page" 【发布时间】:2010-10-19 08:36:53 【问题描述】:我目前正在开发一个 Django 应用程序,它将利用臭名昭著的“分页”技术。我试图弄清楚 django.core.paginator 模块是如何工作的。
我有一个带有问题模型的应用程序。我将使用这个分页器列出所有问题。每页将有 20 个问题。
def show_question(question_pk):
questions = Question.objects.all()
paginator = Paginator(questions, 20)
page = ... # Somehow figure out which page the question is on
return render_to_response('show_question.html', 'page' : page )
在视图中,我将不同的页面列为“... 2, 3, 4, 5, 6, ...” 我想以某种方式突出显示当前页面,就像许多页面可以。
我真的想知道两件事:
-
如何让 Django 找出问题所在的页面?
如何编写模板以正确“突出显示”当前访问的页面?
编辑:对不起,我忘记了这个问题的一部分。我还希望除当前页面之外的任何页面都链接到/questions/ that_page.start_index
。所以基本上每个页面链接都会链接到该页面上的第一个问题。
【问题讨论】:
您希望除当前页面之外的每个页面都链接到该页面上的问题是什么意思?用户将如何更改页面? 我不想传递任何 ?page=4 GET 请求参数或任何东西。我将只对问题 4 使用 /question/4,然后视图将确定该问题在哪个页面上。这就是页面链接真正指向问题的原因。 页面上的第一个问题不会随着更多问题的添加或排序而改变吗?从 REST/HTTP 的角度来看,这意味着 URL 不引用真实资源。这就是 Django 使用 GET 参数的原因:注释 URL 标识的资源的显示特征。 虽然这是真的,但此特定应用程序将仅用于查看预定义的问题。问题永远不会改变。 当前页面名为page_obj
。要查看如何处理它,请查看 simpleisbetterthancomplex.com/tutorial/2016/08/03/…>.
【参考方案1】:
嗯...我从您的评论中看到您不想执行 ol' GET 参数,这是 django.core.paginator 为使用而编写的。为了做你想做的事,我想不出比预先计算每个问题所在的页面更好的方法了。例如,您的视图最终会是这样的:
ITEMS_PER_PAGE = 20
def show_question(question_pk):
questions = Question.objects.all()
for index, question in enumerate(questions):
question.page = ((index - 1) / ITEMS_PER_PAGE) + 1
paginator = Paginator(questions, ITEMS_PER_PAGE)
page = paginator.page(questions.get(pk=question_pk).page)
return render_to_response('show_question.html', 'page' : page )
要在模板中突出显示当前页面,您可以执行类似的操作
% for i in page.paginator.page_range %
% ifequal i page.number %
<!-- Do something special for this page -->
% else %
<!-- All the other pages -->
% endifequal %
% endfor %
至于项目,您将有两个不同的 object_lists 可以使用...
page.object_list
将是当前页面中的对象和
page.paginator.object_list
将是所有对象,与页面无关。这些项目中的每一个都有一个“页面”变量,可以告诉您它们在哪个页面上。
话虽如此,你所做的一切听起来很不合常规。您可能需要重新考虑,但无论如何,祝您好运。
【讨论】:
天哪,天哪!page.paginator.object_list[i].page
听起来可能正是我想要的!我会立即检查的。谢谢!【参考方案2】:
Django,at least 从 1.2 版本开始,允许我们使用纯默认分页模板标签来完成这项任务。
% for page in article_list.paginator.page_range %
% if page == article_list.number %
page
% else %
<a href="/page page "> page </a>
% endif %
% endfor %
article_list 是
的实例paginator = Paginator(article_list, 20)
try:
article_list = paginator.page(int(page))
except (EmptyPage, InvalidPage):
article_list = paginator.page(paginator.num_pages)
【讨论】:
+1 太棒了...是否可以像分页一样编写***(即:prev 1 ... 7 8 9 10 11 ... 500435 next
)。我的意思是...
@suhail,是的,可以这样做,只需使用 django template syntax 修改模板。但我宁愿推荐你试试django-endless-pagination app。它设置简单,并且为各种分页样式提供了合理的默认值。【参考方案3】:
django-pagination 应该做你想做的事,并且包装在一个漂亮的包中,你可以插入和使用。它实质上是将代码从您的视图移动到模板和中间件。
编辑:我刚刚看到您的编辑。
您可以使用% autopaginate object_list %
获取页面上的当前对象,它将object_list
替换为任何给定页面的当前对象。你可以遍历它,如果你想要第一个,你应该能够把它当作一个列表来处理并执行object_list[0]
。
如果您想将其保留在您的视图中,您可以执行以下操作:
def show_question(question_pk):
questions = Question.objects.all()
paginator = Paginator(questions, 20)
return render_to_response('show_question.html', 'page' : paginator )
在您的模板中,您可以通过以下方式访问当前页面:
# Gives you the starting index for that page.
# For example, 5 objects, and you're on the second page.
# start_index will be 3.
page.start_index
# You can access the current page number with:
# 1-based index
page.number
有了它,你应该能够做你需要的一切。 有几个很好的例子here。
【讨论】:
感谢您的评论。但是,对我来说,django-pagination 似乎只是内置的分页功能,只是将逻辑从代码移到模板和中间件中。是这样吗? 基本上,是的。如果您想将分页登录信息保留在您的视图中,我更新了我的答案。以上是关于Django分页和“当前页面”的主要内容,如果未能解决你的问题,请参考以下文章
ExtJs - 基于远程数据的分页和缓冲网格,没有远程分页和过滤