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的理解 在进入正文之 ...
随机推荐
- img的空白内容如何处理
给img加一个 vertical-align: bottom;
- js判断手机登陆用户
uaredirect.js function uaredirect(f){try{if(document.getElementById("bdmark")!=null){retur ...
- VSTO Project 客户端自动发送邮件
利用office vsto功能,抓取我们选择的任务,根据配置节,邮件发送内容,最终根据任务名称,任务开始结束时间,任务资源名称,发送邮件给任务资源. 这是我的VSTO界面. 配置我们发送邮件的服务器地 ...
- 原生js的常见封装
)); } ;;;;]){ ]; ] = ;;;,) ,) ,) ,) ,) , ...
- Java OOP——第二章 继承
1. 继承: ●继承是面向对象的三大特征之一,是JAVA实现代码重用的重要手段之一: ●继承是代码重用的一种方式,将子类共有的属性和行为放到父类中: ●JAVA只支持单继承,即每一个类只有一个父类,继 ...
- 在Pycharm中导入第三方模块库(诸如:matplotlib、numpy等)
在Pycharm中导入第三方模块库 一.打开pycharm: 二.点击菜单上的“file” -> “setting”: 三.步骤二完成后出现界面如下所示.选中你的项目(比如thisyan Pro ...
- 帆软中使用switch将控件的显示值“传递”给单元格
如下图,控件的实际值和显示值是我们自定义的. 当我们选择控件时,想要在某个单元格内显示控件的显示值.一般我们在单元格内直接 $控件名 可以获得控件值.比如当我们选择事故数时,我们自然不能在单元格内直 ...
- 第1章 MATLAB概述
MATLAB系统由~开发环境.~语言.~数学函数库.~图形处理系统.~应用程序接口(API)5大部分组成. 界面 命令行中的语句格式 命令行的语句格式:>>变量=表达式(没有>> ...
- HyperLedger Fabric 1.4 关键技术(6.4)
本节介绍从最底层的账本开始,逐一讲解账本的结构和存储.智能合约的编写和部署.通道的操作.节点的背书和提交.排序的共识和客户端SDK的接口调用,与交易流程顺序相反,由里及表的说明Fabric最关键的技术 ...
- python--基本类型之列表
Lest(列表): 定义和创建列表: 列表:是python以及其他语言中最常用的数据结构之一.python用 [] 来解析列表列表是可变的.--可以改变列表的内容可以用切片 a=['张三','李四', ...