django视图之分页
在网站开发时,肯定会遇到分页的事情需要处理,在django中也是如此,在Django中处理分页一般会使用到两个类django.core.paginator.Paginator和django.core.paginator.Page,要想在Django中做分页处理,首先我们就需要了解一下这两个类。
首先在使用Django的通用视图时,在get_context_data方法中返回的内容中就包含当前页的分类信息,get_context_data方法的返回值中封装了当前页的分页信息,即Paginator和Page类的对象。其中Paginator被封装成的对象对应的键为'paginator',Page被封装成的对象对应的键为'page_obj'
Paginator类对象常用属性和方法,主要是整个列表相关信息:
count:总共有多少条数据。
num_pages:总共有多少页。
page_range:页面的区间。比如有三页,那么就range(1,4)。
Page类对象常用属性和方法,主要是当前页相关信息:
has_next():是否还有下一页。
has_previous():是否还有上一页。
next_page_number():下一页的页码。
previous_page_number():上一页的页码。
number:当前页码。
start_index():当前这一页的第一条数据的索引值。
end_index():当前这一页的最后一条数据的索引值。
普通分页:在手动写分页的时候,我们只需要使用到原生的Paginator和Page类对象,而这些对象直接被封装在get_context_data的返回值之中,我们直接使用就可以了,借助于bootstrap的分页相关样式,在模板中的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文章列表</title>
{# 引入bootstrap样式 #}
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<ul>
{# 列表内容 #}
{% for article in article_list %}
<li>
{{ article.title }}
</li>
{% endfor %}
<ul class="pagination">
{# 分页内容 #}
{# 上一页 #}
{% if page_obj.has_previous %}
<li><a href="{% url 'front:article_list' %}?page={{ page_obj.previous_page_number }}">上一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0);">上一页</a></li>
{% endif %}
{# 中间页 #}
{% for num_page in paginator.page_range %}
{% if page_obj.number == num_page %}
<li class="active"><a href="{% url 'front:article_list' %}?page={{ num_page }}">{{ num_page }}</a></li>
{% else %}
<li><a href="{% url 'front:article_list' %}?page={{ num_page }}">{{ num_page }}</a></li>
{% endif %}
{% endfor %}
{# 下一页 #}
{% if page_obj.has_next %}
<li><a href="{% url 'front:article_list' %}?page={{ page_obj.next_page_number }}">下一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0);">下一页</a></li>
{% endif %}
</ul>
</ul>
</body>
</html>
上面的分页写法,如果页数过于多,那么将会很难看,而且也不是很实用,所以上面的分页写法只适合于很少的页数的分页,不是通用的写法,下面我们就来编写一种通用的分页写法
通用分页算法:通用分页算法需要我们对原始的Paginator和Page对象进行进一步的封装,使用封装后的数据进行分页,首先我们写一个函数去封装这两个对象,例如get_pagination_data:
def get_context_data(self, **kwargs):
context = super(ArticleListView, self).get_context_data(**kwargs)
paginator = context.get('paginator') # 包含整体数据的相关信息
page_obj = context.get('page_obj') # 包含当前页数据相关的信息
pagination_data = self.get_pagination_data(paginator, page_obj)
context.update(pagination_data)
return context
def get_pagination_data(self, paginator, page_obj, around_count=2):
left_has_more = False
right_has_more = False
current_page = page_obj.number
if current_page <= around_count + 2:
left_range = range(1, current_page)
else:
left_has_more = True
left_range = range(current_page-around_count,current_page)
if current_page >= paginator.num_pages - around_count-1:
right_range = range(current_page+1, paginator.num_pages+1)
else:
right_has_more = True
right_range = range(current_page+1, current_page+around_count+1)
pagination_data = {
'left_has_more': left_has_more,
'right_has_more': right_has_more,
'left_range': left_range,
'right_range': right_range
}
return pagination_data
在模板使用封装的数据,去进行分页,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文章列表</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<ul>
{% for article in article_list %}
<li>
{{ article.title }}
</li>
{% endfor %}
<ul class="pagination">
{# 上一页 #}
{% if page_obj.has_previous %}
<li><a href="{% url 'front:article_list' %}?page={{ page_obj.previous_page_number }}">上一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0);">上一页</a></li>
{% endif %}
{# 中间左边部分 #}
{% if left_has_more %}
<li><a href="{% url 'front:article_list' %}?page=1">1</a></li>
<li><a href="javascript:void(0);">...</a></li>
{% for page in left_range %}
<li><a href="{% url 'front:article_list' %}?page={{ page }}">{{ page }}</a></li>
{% endfor %}
{% else %}
{% for page in left_range %}
<li><a href="{% url 'front:article_list' %}?page={{ page }}">{{ page }}</a></li>
{% endfor %}
{% endif %}
{# 中间部分当前页 #}
<li class="active"><a href="{% url 'front:article_list' %}?page={{ page_obj.number }}">{{ page_obj.number }}</a></li>
{# 中间右边部分 #}
{% if right_has_more %}
{% for page in right_range %}
<li><a href="{% url 'front:article_list' %}?page={{ page }}">{{ page }}</a></li>
{% endfor %}
<li><a href="javascript:void(0);">...</a></li>
<li><a href="{% url 'front:article_list' %}?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a></li>
{% else %}
{% for page in right_range %}
<li><a href="{% url 'front:article_list' %}?page={{ page }}">{{ page }}</a></li>
{% endfor %}
{% endif %}
{# 下一页 #}
{% if page_obj.has_next %}
<li><a href="{% url 'front:article_list' %}?page={{ page_obj.next_page_number }}">下一页</a></li>
{% else %}
<li class="disabled"><a href="javascript:void(0);">下一页</a></li>
{% endif %}
</ul>
</ul>
</body>
</html>
使用上述两种方法基本可以完成分页的业务需求
django视图之分页的更多相关文章
- django之快速分页
本文介绍djanog两种分页,第一是普通分页,第二是使用haystack全文检索的分页. 1.django自带分页功能,这个功能非常好用.基本知识点:Django提供了数据分页的类,这些类被定义在dj ...
- Django中的分页,cookies与session
cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...
- django: django rest framework 分页
django: django rest framework 分页 2018年06月22日 13:41:43 linux_player_c 阅读数:665更多 所属专栏: django 实战 版权声 ...
- django: rest-framework的 分页和过滤
django: rest-framework的 分页和过滤 2018年06月28日 10:09:01 weixin_42359464 阅读数:136 标签: flaskrestframeworkdja ...
- django上课笔记2-视图CBV-ORM补充-Django的自带分页-Django的自定义分页
一.视图CBV 1.urls url(r'^login.html$', views.Login.as_view()), 2.views from django.views import View cl ...
- Django视图扩展类
Django视图扩展类 扩展类必须配合GenericAPIView使用扩展类内部的方法,在调用序列化器时,都是使用get_serializer 需要自定义get.post等请求方法,内部实现调用扩展类 ...
- Django - Xadmin (三) 分页、搜索和批量操作
Django - Xadmin (三) 分页.搜索和批量操作 分页和 ShowList 类 因为 list_view 视图函数里面代码太多,太乱,所以将其里面的用于处理表头.处理表单数据的关键代码提取 ...
- Django 内置分页的简单使用
1, 文档 https://docs.djangoproject.com/en/1.11.1/topics/pagination/ 2,视图 from django.core.paginator im ...
- [diango]理解django视图工作原理
前言:正确理解django视图view,模型model,模板的概念及其之间的关联关系,才能快速学习并上手使用django制作网页 本文主要讲解自己在学习django后对视图view的理解 在进入正文之 ...
随机推荐
- 简明 ES6 模块
简明 ES6 模块 1.什么是模块 模块就是一段代码,这段代码可以反复使用,经常单独写成一个文件,一旦加载会立即执行. 2.导出 导出有 2 种方式:命名导出和默认导出,分别用关键字export和ex ...
- 让微信内置浏览器兼容clipboard.js 复制粘贴 ios 安卓
<!--js copy事件--><script type="text/javascript" src="/static/js/clipboard.min ...
- oracle 11g grid软件安装[20180121]
实验环境: 系统->Redhat 6.5 Oracle软件版本->oracle 11.2.0.4.0 系统初始化 设定hosts主机名和对应IP地 ...
- SpringBoot配置redis和分布式session-redis
springboot项目 和传统项目 配置redis的区别,更加简单方便,在分布式系统中,解决sesssion共享问题,可以用spring session redis. 1.pom.xml <d ...
- springmvc处理器拦截器
处理器拦截器(interceptor)是做什么用的? 想知道处理拦截器做什么用的,你要先了解下处理·流程链·. 前端控制器(dispatcherServlet)接收到请求,通过handleMappin ...
- (转)手游应该怎么做 UI 设计?
之前一直做互动设计,在UI上有一些积累. 转战手游后发现,有着标准.互动方式.用户行为等等与常规大屏UI设计的不同,但是在设计流程,思考方式上是一样的. 以目前项目中一个界面为例(未完成版本)来说一下 ...
- 解决百度编辑器ueditor插入视频网址保存不了问题
问题:如下图,在百度编辑器中插入视频,视频网址可以识别,但是提交内容后视频却显示不了. 解决:这个问题主要是编辑器中会过滤一些html标签,所以可以给标签添加白名单. 修改 ueditor.confi ...
- python计算MD5
python有自带的MD5模块hashlib,用起来简单很多.Python Hashlib模块的使用说明 http://docs.python.org/2/library/hashlib.htmlfd ...
- unity独立游戏开发日志2018/09/22
f::很头痛之前rm做的游戏在新电脑工程打不开了...只能另起炉灶... 还不知道新游戏叫什么名...暂且叫方块世界.(素材已经授权) 首先是规划下场景和素材文件夹的建立. unity常用的文件夹有: ...
- P1049 装箱问题
装箱问题 题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱内,使 ...