Django分页Paginator和Page的用法

899次阅读
没有评论

Django 中实现分页功能非常简单。因为 Django 已经内置了两个处理分类的类。分别 是 Paginator 和 Page 。 Paginator 用来管理整个分类的一些属性, Page 用来管理当前这个分 页的一些属性。通过这两个类,就可以轻松的实现分页效果。以下对这两个类进行讲解。

Paginator 类

Paginator 是用来控制整个分页的逻辑的。比如总共有多少页,页码区间等.

创建Paginator对象:

class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True) ,其中的参 数解释如下:

  1. object_list (必选):列表,元组, QuerySet 或者是任何可以做切片操作的对象。会将这个里面的对象进行分页。 QuerySet带有count() or __len__()方法的列表,元组或其他可分片对象。为了保持一致的分页,QuerySet应该对s进行排序,例如在模型中使用order_by() 子句或缺省值ordering。
  2. per_page (必选):分页中,一页展示多少条数据,包含在页面上的最大项目数 ,不包括 orphans。
  3. orphans (可选):用来控制最后一页元素的个人如果少于 orphans 指定的个数的时候,就会将多余 的添加到上一页中。
  4. allow_empty_first_page(可选) :如果 object_list 没有任何数据,并且这个参数设置为 True , 那么就会抛出 EmptyPage 异常。

常用属性和方法:

  1. Paginator.page(number) :获取 number 这页的 Page 对象。
  2. count :传进来的 object_list 总共的数量。
  3. num_pages :总共的页数。
  4. page_range :页码的列表。比如 [1,2,3,4]

Page 类:

得到Page对象:Paginator.page() 使用Page类构造对象生成Page对象

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Page</span>(<span class="hljs-title">object_list</span>, <span class="hljs-title">number</span>, <span class="hljs-title">paginator</span>)</span>

常用属性和方法:

  1. has_next() :是否还有下一页。
  2. has_previous() :是否还有上一页。
  3. next_page_number() :下一页的页码。
  4. previous_page_number() :上一页的页码。
  5. object_list :在当前这页上的对象列表。
  6. number :当前的页码。
  7. paginator :获取 Paginator 对象。

例一:

<span class="hljs-comment">#views.py</span>
<span class="hljs-keyword">from</span> django.shortcuts <span class="hljs-keyword">import</span> render_to_response
<span class="hljs-keyword">from</span> django.core.paginator <span class="hljs-keyword">import</span> Paginator

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">classify</span><span class="hljs-params">(request)</span>:</span>
    <span class="hljs-string">"""
    注意:objects可以为:列表/元组,Django QuerySet或任何其他对象
    """</span>
    
    <span class="hljs-comment"># 获取所有的对象的列表</span>
    objects = goods.objects.all() <span class="hljs-comment"># objects = ['john', 'paul', 'george', 'ringo']</span>
    
    <span class="hljs-comment"># 把对象分成 2 个一页</span>
    paginator = Paginator(objects, <span class="hljs-number">2</span>)
    
    <span class="hljs-comment"># 获取分页器里面的Page总数</span>
    paginator.count     <span class="hljs-comment"># -> 4</span>
    
    <span class="hljs-comment"># 获取Page的数量</span>
    paginator.num_pages  <span class="hljs-comment"># -> 2</span>
    
    <span class="hljs-comment"># 获取Page数目的范围(返回一个range_iterator对象)</span>
    paginator.page_range  <span class="hljs-comment"># -> range(1, 3)</span>
    
    <span class="hljs-comment"># 获得第一/二页的Page对象</span>
      <span class="hljs-comment"># <Page 1 of 2> </span>
      <span class="hljs-comment"># 返回Page具有给定从1开始的索引的对象。InvalidPage如果给定页码不存在则引发 。</span>
    page1 = paginator.page(<span class="hljs-number">1</span>)
      <span class="hljs-comment"># <Page 1 of 2>django2以上新增功能:返回Page具有给定的基于1的索引的对象</span>
      <span class="hljs-comment">#同时处理超出范围和无效页码(超出范围不会报错,默认返回最后一个Page对象)</span>
    page2 = paginator.get_page(<span class="hljs-number">2</span>)  
    
    <span class="hljs-comment"># 获得第一个Page对象中的所有内容</span>
    page1.object_list  <span class="hljs-comment"># -> ['john', 'paul']</span>
    
    <span class="hljs-comment"># 判断下一个Page对象是否存在</span>
    page2.has_next()  <span class="hljs-comment"># -> False</span>
    <span class="hljs-comment"># 判断上一个Page对象是否存在 </span>
    page1.has_previous()  <span class="hljs-comment">#-> False</span>
    
    <span class="hljs-comment"># 判断是否还有其他Page对象</span>
    page2.has_other_pages()   <span class="hljs-comment"># True</span>
    
    <span class="hljs-comment"># 返回下一个Page对象的索引。如果没有,则触发EmptyPage</span>
    page2.next_page_number()  <span class="hljs-comment"># 报错</span>
    <span class="hljs-comment"># 返回上一个Page对象的索引。如果没有,则触发EmptyPage</span>
    page2.previous_page_number()  <span class="hljs-comment"># 1</span>
    
    <span class="hljs-comment"># 返回第一个Page对象中的第一个元素的索引值(原对象的第一个元素的位置为1)</span>
    page1.start_index()  <span class="hljs-comment"># 1</span>
    <span class="hljs-comment"># 返回第二个Page对象中的第一个元素的索引值(原对象的第一个元素的位置为1)</span>
    page2.start_index()  <span class="hljs-comment"># 3</span>
    <span class="hljs-comment"># 返回第二个Page对象里面的第一个对象的最后一个元素位置(原对象的第一个元素的位置为1)</span>
    page1.end_index()  <span class="hljs-comment"># 2</span>
    <span class="hljs-comment"># 返回第二个分页器里面的第一个对象的最后一个元素位置(原对象的第一个元素的位置为1)</span>
    page2.end_index()  <span class="hljs-comment"># 4</span>
    <span class="hljs-comment"># 获取当前页码</span>
    current_page_num = page1.number    
    <span class="hljs-keyword">return</span> render_to_response(<span class="hljs-string">'index.html'</span>)

例二:

要求不复杂的话,直接使用以下的的设置即可,如有其它需求,可根据需求自定义。

使用方法:

1、导入分页所需的类

<span class="hljs-selector-tag">from</span> <span class="hljs-selector-tag">django</span><span class="hljs-selector-class">.core</span><span class="hljs-selector-class">.paginator</span> <span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">Paginator</span>, <span class="hljs-selector-tag">EmptyPage</span>, <span class="hljs-selector-tag">PageNotAnInteger</span>

2、对需要的数据进行处理

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">index</span><span class="hljs-params">(request)</span>:</span>

    news = Article.objects.all().order_by(<span class="hljs-string">'-id'</span>)<span class="hljs-comment">#把需要分页的数据实例化</span>

    page = request.GET.get(<span class="hljs-string">'page'</span>)<span class="hljs-comment"># 获取分页数</span>
    paginator = Paginator(news, <span class="hljs-number">10</span>)<span class="hljs-comment">#设置一页显示多少条数据(news为要分页的数据)</span>
    <span class="hljs-keyword">try</span>:
        news = paginator.page(page)  <span class="hljs-comment"># 获取当前页码的记录</span>
    <span class="hljs-keyword">except</span> PageNotAnInteger:
        news = paginator.page(<span class="hljs-number">1</span>)  <span class="hljs-comment"># 如果用户输入的页码不是整数时,显示第1页的内容</span>
    <span class="hljs-keyword">except</span> EmptyPage:
        news = paginator.page(paginator.num_pages)  <span class="hljs-comment"># 如果用户输入的页数不在系统的页码列表中时,显示最后一页的内容</span>
    <span class="hljs-keyword">return</span> render(request, <span class="hljs-string">'index.html'</span>, locals())

3、前端分页效果:

<div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"pages"</span>>
    <span class="xml"><span class="hljs-tag"><<span class="hljs-name">ul</span>></span>
        {# 首页按钮,固定page=1 #}
        <span class="hljs-tag"><<span class="hljs-name">li</span>></span><span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">'?page=1'</span>></span>首页<span class="hljs-tag"></<span class="hljs-name">a</span>></span><span class="hljs-tag"></<span class="hljs-name">li</span>></span>
        {# 如果上一页还有数据,那么让其可继续点击进入上一页 #}
        {% if news.has_previous %}
            <span class="hljs-tag"><<span class="hljs-name">li</span>></span><span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"?page={{ news.previous_page_number }}"</span> <span class="hljs-attr">data-ey_fc35fdc</span>=<span class="hljs-string">"html"</span> <span class="hljs-attr">data-tmp</span>=<span class="hljs-string">"1"</span>></span>上一页<span class="hljs-tag"></<span class="hljs-name">a</span>></span>
            <span class="hljs-tag"></<span class="hljs-name">li</span>></span>
            {# 如果上一页没有数据了,那么不让做任何操作 #}
        {% else %}
        {% endif %}

        {# 由后端经逻辑判断后的page_range页数列表进行迭代 #}
        {% for num in news.paginator.page_range %}
            {# 如果循环的页码与当前查看的页码相等,那么就让其高亮显示 #}
            {% if num == news.number %}
                <span class="hljs-tag"><<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"thisclass"</span>></span><span class="hljs-tag"><<span class="hljs-name">a</span>></span>{{ num }}<span class="hljs-tag"></<span class="hljs-name">a</span>></span><span class="hljs-tag"></<span class="hljs-name">li</span>></span>
            {% else %}
                <span class="hljs-tag"><<span class="hljs-name">li</span>></span><span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"?page={{ num }}"</span> <span class="hljs-attr">data-ey_fc35fdc</span>=<span class="hljs-string">"html"</span> <span class="hljs-attr">data-tmp</span>=<span class="hljs-string">"1"</span>></span>{{ num }}<span class="hljs-tag"></<span class="hljs-name">a</span>></span><span class="hljs-tag"></<span class="hljs-name">li</span>></span>
            {% endif %}
        {% endfor %}

        {# 如果当前页还有下一页,那么让其可以点击进入下一页 #}
        {% if news.has_next %}
            <span class="hljs-tag"><<span class="hljs-name">li</span>></span><span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"?page={{ news.next_page_number }}"</span> <span class="hljs-attr">data-ey_fc35fdc</span>=<span class="hljs-string">"html"</span> <span class="hljs-attr">data-tmp</span>=<span class="hljs-string">"1"</span>></span>下一页<span class="hljs-tag"></<span class="hljs-name">a</span>></span><span class="hljs-tag"></<span class="hljs-name">li</span>></span>
        {% endif %}

        {# 跳转到尾页,让page参数直接等于总页数 #}
        <span class="hljs-tag"><<span class="hljs-name">li</span>></span><span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">'?page={{ paginator.num_pages }}'</span>></span>尾页<span class="hljs-tag"></<span class="hljs-name">a</span>></span><span class="hljs-tag"></<span class="hljs-name">li</span>></span>
    <span class="hljs-tag"></<span class="hljs-name">ul</span>></span></span>
<<span class="hljs-regexp">/div></span>

效果如图:

Django分页Paginator和Page的用法

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:wuyou2019-10-08发表,共计4303字。
新手QQ群:570568346,欢迎进群讨论 Python51学习
评论(没有评论)