Django 1.X和2.0下利用自带分页Paginator类实现分页功能

Django作为Python Web开发框架的一哥,提供了企业级网站开发所需要的几乎所有功能,其中就包括自带分页功能。利用Django自带的Paginator类,我们可以很轻松地实现分页。Django 2.0和1.X最大的不同在于新增了get_page()方法。我们现在来具体看看有什么不同。

Django 1.X 和Django 2.0下实现分页

利用Django实现分类非常简单,我们只需要修改views.py和模板template。Django 1.X下实现分页代码如下:

# app/views.py - 基于函数的视图

fromdjango.core.paginatorimportPaginator, EmptyPage, PageNotAnInteger

from.modelsimportArticle

from django.shortcuts import render

defarticle_list(request):article_list=Article.objects.all()paginator=Paginator(article_list,10)# 实例化一个分页对象, 每页显示10个page=request.GET.get('page')# 从URL通过get页码,如?page=3try:articles=paginator.page(page)# 获取某页对应的记录exceptPageNotAnInteger:# 如果页码不是个整数articles=paginator.page(1)# 提取第一页的记录exceptEmptyPage:# 如果页码太大,没有相应的记录articles=paginator.page(paginator.num_pages)# 提取最后一页的记录returnrender(request,'article_list.html',{'articles':articles})

你注意到没有?上段代码的try和2个except非常重要,但是看上去有些冗余。Django 2.0下新增了get_page()方法,可以将代码大大简化(如下图所示)。它所实现的功能与上面是一样的。当用户提交的页码不是整数时,提取第一页记录。当用户输入的页码太大时,只提取最后一页记录。

fromdjango.core.paginatorimportPaginator, EmptyPage, PageNotAnInteger

from.modelsimportArticle

from django.shortcuts import render

defarticle_list(request):article_list=Article.objects.all()paginator=Paginator(article_list,10)# 实例化一个分页对象, 每页显示10个page=request.GET.get('page')# 从URL通过get页码,如?page=3

articles=paginator.get_page(page)# 获取某页对应的记录, 如果returnrender(request,'article_list.html',{'articles':articles})

Django 1.X和2.0下的模板是一样的。这里提供两种显示方案。

模板一: 上一页, Page 1 of 3, 下一页

#app/templates/app/article_list.html

{% for article in articles %}

{{ article.title }}

{% endfor %}

class="step-links">

{% if articles.has_previous %}

«first

previous

{% endif %}

class="current">

Page {{ articles.number }} of {{ articles.paginator.num_pages }}.

{% if articles.has_next %}

next

last»

{% endif %}

模板二: Page 1, 2, 3, 4, 5, 6, 7, 8, ... (推荐)

#app/templates/app/article_list.html

# Pagination style 2

{% for article in articles %}

{{ article.title }}

{% endfor %}

{% if articles.has_previous %}

aria_hidden="true">«

{% endif %}

{% for page_num in articles.paginator.page_range %}

{% if page_num == articles.number %}

{}

{% else %}

{}

{% endif %}

{% endfor %}

{% if articles.has_next %}

aria_hidden="true">»

{% endif %}

Django如何在基于类的视图里使用分页?

上述案例里我们使用了函数试图,很容易定义page对象, 并传递给模板,例如articles。但是如果我们希望使用基于类的视图,我们该如何实现分页呢?其实操作非常简单。我们只需在视图中加入paginate_by = number即可。

from. modelsimportArticle

fromdjango.views.genericimportListView

classArticleListView(ListView):

model = Article# 等于 queryset = models.Article.objects.all()

template_name ='app/article_list.html'# 可选的

context_object_name ="article_list"# 默认context名字

paginate_by =10# 每页10项

此时模板article_list.html也需要做出相应调整,如下图所示。Django会先对是否分页is_paginated做个判断,如果有,就会自动生成个page_obj分页对象传递到模板。

{% if article_list %}

{% for article in article_list %}

{{ article.title }}

{% endfor %}

{% if is_paginated %}

{% if page_obj.has_previous %}

Previous

{% endif %}

Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.

{% if page_obj.has_next %}

Next

{% endif %}

{% else %}

Articles

No article yet

{% endif %}

本文【Python与Django大咖之路】原创,如果喜欢我的文章,欢迎关注我的微信公众号。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180507G0GHY000?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券