在网站开发时,肯定会遇到分页的事情需要处理,在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视图之分页的更多相关文章

  1. django之快速分页

    本文介绍djanog两种分页,第一是普通分页,第二是使用haystack全文检索的分页. 1.django自带分页功能,这个功能非常好用.基本知识点:Django提供了数据分页的类,这些类被定义在dj ...

  2. Django中的分页,cookies与session

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  3. django: django rest framework 分页

    django: django rest framework 分页 2018年06月22日 13:41:43 linux_player_c 阅读数:665更多 所属专栏: django 实战   版权声 ...

  4. django: rest-framework的 分页和过滤

    django: rest-framework的 分页和过滤 2018年06月28日 10:09:01 weixin_42359464 阅读数:136 标签: flaskrestframeworkdja ...

  5. 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 ...

  6. Django视图扩展类

    Django视图扩展类 扩展类必须配合GenericAPIView使用扩展类内部的方法,在调用序列化器时,都是使用get_serializer 需要自定义get.post等请求方法,内部实现调用扩展类 ...

  7. Django - Xadmin (三) 分页、搜索和批量操作

    Django - Xadmin (三) 分页.搜索和批量操作 分页和 ShowList 类 因为 list_view 视图函数里面代码太多,太乱,所以将其里面的用于处理表头.处理表单数据的关键代码提取 ...

  8. Django 内置分页的简单使用

    1, 文档 https://docs.djangoproject.com/en/1.11.1/topics/pagination/ 2,视图 from django.core.paginator im ...

  9. [diango]理解django视图工作原理

    前言:正确理解django视图view,模型model,模板的概念及其之间的关联关系,才能快速学习并上手使用django制作网页 本文主要讲解自己在学习django后对视图view的理解 在进入正文之 ...

随机推荐

  1. Vue nodejs商城项目-登录模块

    一.登录功能 后端server/routes/users.js var User = require('./../models/users.js');   // 二级路由 // 登录接口 router ...

  2. Django-rest-framework(三)view and viewsets使用

    DRF 中有多种view和viewsets,我整理了一下,如下图所示,接下来,我们分别了解下view,viewsets. APIView 所有的view,viewsets都是继承APIView,而AP ...

  3. 基于Cent os 云服务器中SVN 服务器的搭建---具体实践是可行的 一次备注便于后续查找

    https://blog.csdn.net/shadowyingjian/article/details/80588544http://www.hongyanliren.com/2015m04/329 ...

  4. iOS | 实现拖拽CollectionViewCell排序

    现在很多项目都会用到类似拖动的效果,比如今日头条和网易新闻之类的资讯类产品,都有用该技术设置模块顺序的操作. 在iOS9.0之后,苹果提供相关的方法,非常方便. 设定三个私有属性 @property( ...

  5. 青蛙的约会(exgcd/扩展欧几里得)

    题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清 ...

  6. 【CodeForces 915 C】Permute Digits(思维+模拟)

    You are given two positive integer numbers a and b. Permute (change order) of the digits of a to con ...

  7. IPC进程间通信---消息队列

    消息队列 消息队列:消息队列是一个存放在内核中的消息链表,每个消息队列由消息队列标识符标识.与管道不同的是消息队 列存放在内核中,只有在内核重启(即操作系统重启)或者显式地删除一个消息队列时,该消息队 ...

  8. jdbc学习笔记02

    数据库连接池 DBCP DataBase Conection Pool:数据库连接池 如果没有数据库连接池,每一次业务都需要服务器和数据库服务器建立一次连接,业务处理完连接断开,如果有1万次业务处理, ...

  9. Percona XtraDB Cluster 5.7安装配置

    优点:1.准同步复制2.多个可同时读写节点,可实现写扩展,较分片方案更进一步3.自动节点管理4.数据严格一致5.服务高可用缺点:1.只支持innodb引擎2.所有表都要有主键3.所有的写操作都将发生在 ...

  10. Docker 运行MangoDB

    1.Docker运行MangoDB镜像 #创建挂载目录 cd /opt/docker_cfg mkdir -vp mongo/db #获取mongodb镜像 [root@localhost xiaog ...