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的理解 在进入正文之 ...
随机推荐
- bitmap和drawable的相互转化以及setImageResource(),setImageDrawable(),setImageBitmap()
从本地获取drawable图片:getResources().getDrawable(R.drawable.**) 获取bitmap:Bitmap b=BitmapFactory().decodeRe ...
- SQL里的concat() 以及group_concat() 函数的使用
实例参考:https://blog.csdn.net/mary19920410/article/details/76545053 一 concat()函数 1.功能:将多个字符串连接成一个字符串. 2 ...
- 利用JQUERY实现多个AJAX请求等待
利用JQUERY实现多个AJAX请求等待 li {list-style-type:decimal;}.wiz-editor-body ol.wiz-list-level2 > li {list- ...
- 如何用 npm 同时执行两条监听命令
在日常项目中启动项目 需要启动项目可能需要不止一条命令 这就很麻烦 要开启两个bash 很麻烦 终于找到了比较好的解决方案 例如我的: npm run dev //启动项目项目 npm run jso ...
- 部署node api的二三事
当接到node开发node api的时候,我就想用docker来部署,众所周知,node的版本更新迭代很快.很多以前需要babel后才能采用的方法正在不断被node 原生的支持.如果随便更换生产服务器 ...
- Angular : 绑定, 参数传递, 路由
如何把jquery导入angular npm install jquery --savenpm install @type/jquery --save-dev "node_modules/z ...
- ECSHOP和SHOPEX快递单号查询EMS插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- emlog博客插件分享openSug
emlog博客插件百度搜索下拉提示框openSug.js发布上线啦: 下载:https://www.opensug.org/faq/.../opensug.emlog_v1.0.0.zip[~4KB]
- Python基础教程学记(1)
引言 Python是什么?——Python是一种面向对象的解释性高级编程语言,具有动态语义.这句话的要点在于,Python是一种知道如何不妨碍你编写程序的编程语言.它让你能够毫无困难地实现所需的功能, ...
- Centos安装docker#避免很多坑
采用yum方式安装 安装: step 1: 安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 Step 2 ...