• Django 分页器的使用


     Django 分页器的使用

     Django作为Python Web开发框架的一哥,提供了企业级网站开发所需要的几乎所有功能,其中就包括自带分页功能。利用Django自带的Paginator类,我们可以很轻松地实现分页。Django 2.0和1.X最大的不同在于新增了get_page()方法。我们现在来具体看看有什么不同。

     Django 1.X 和Django 2.0下实现分页

     利用Django实现分类非常简单,我们只需要修改views.py和模板template。Django 1.X下实现分页代码如下:

    # app/views.py - 基于函数的视图

    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    from .models import Article
    
    from django.shortcuts import render
    
     
    
    def article_list(request):
    
        article_list = Article.objects.all()
    
        paginator = Paginator(article_list, 10)  # 实例化一个分页对象, 每页显示10个
    
     
    
        page = request.GET.get('page')  # 从URL通过get页码,如?page=3
    
        try:
    
            articles = paginator.page(page)  # 获取某页对应的记录
    
        except PageNotAnInteger:  # 如果页码不是个整数
    
            articles = paginator.page(1)  # 提取第一页的记录
    
        except EmptyPage:  # 如果页码太大,没有相应的记录
    
            articles = paginator.page(paginator.num_pages)  # 提取最后一页的记录
    
     
    
        return render(request, 'article_list.html', {'articles': articles})

    你注意到没有?上段代码的try和2个except非常重要,但是看上去有些冗余。Django 2.0下新增了get_page()方法,可以将代码大大简化(如下图所示)。它所实现的功能与上面是一样的。当用户提交的页码不是整数时,提取第一页记录。当用户输入的页码太大时,只提取最后一页记录。

    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    from .models import Article
    
    from django.shortcuts import render
    
     
    
    def article_list(request):
    
        article_list = Article.objects.all()
    
        paginator = Paginator(article_list, 10)  # 实例化一个分页对象, 每页显示10个
    
     
    
        page = request.GET.get('page')  # 从URL通过get页码,如?page=3
    
       articles = paginator.get_page(page)  # 获取某页对应的记录, 如果
    
       
    
        return render(request, 'article_list.html', {'articles': articles})

    Django 1.X和2.0下的模板是一样的。这里提供两种显示方案。

    模板一: 上一页, Page 1 of 3, 下一页

    #app/templates/app/article_list.html

    {% for article in articles %}
    
        {{ article.title }}  
    
    {% endfor %}
    
     
    
    <div class="pagination">
    
        <span class="step-links">
    
            {% if articles.has_previous %}
    
                <a href="?page=1">« first</a>
    
                <a href="?page={{ articles.previous_page_number }}">previous</a>
    
            {% endif %}
    
     
    
            <span class="current">
    
                Page {{ articles.number }} of {{ articles.paginator.num_pages }}.
    
            </span>
    
     
    
            {% if articles.has_next %}
    
                <a href="?page={{ articles.next_page_number }}">next</a>
    
                <a href="?page={{ articles.paginator.num_pages }}">last »</a>
    
            {% endif %}
    
        </span>
    
    </div>
    
     

    模板二: Page 1, 2, 3, 4, 5, 6, 7, 8, ... (推荐)

    #app/templates/app/article_list.html

    # Pagination style 2
    
    {% for article in articles %}
    
        {{ article.title }}
    
    {% endfor %}
    
    <div class="pagination">
    
    <nav>
    
        <ul class="pagination">
    
            {% if articles.has_previous %}
    
            <li class="">
    
            <a href="?page={{ articles.previous_page_number }}" aria-label="Previous">
    
            <span aria_hidden="true">«</span></a>
    
            </li>
    
            {% endif %}
    
            
    
            {% for page_num in articles.paginator.page_range %}
    
                {% if page_num == articles.number %}
    
             <li class="active"><a href="?page={{ page_num }}">{{page_num}}</a> </li>
    
                {% else %}
    
             <li class=""><a href="?page={{ page_num }}">{{page_num}}</a> </li>
    
                {% endif %}
    
            {% endfor %}
    
            
    
            {% if articles.has_next %}
    
             <li class="">
    
                  <a href="?page={{ articles.next_page_number }}" aria-label="Next">
    
                      <span aria_hidden="true">»</span></a>
    
            </li>
    
          {% endif %}
    
        </ul>
    
    </nav>
    
    </div>

    Django如何在基于类的视图里使用分页?

    上述案例里我们使用了函数试图,很容易定义page对象, 并传递给模板,例如articles。但是如果我们希望使用基于类的视图,我们该如何实现分页呢?其实操作非常简单。我们只需在视图中加入paginate_by = number即可。

    from. models import Article
    
    from django.views.generic import ListView
    
     
    
    class ArticleListView(ListView):
    
        model = Article  # 等于 queryset = models.Article.objects.all()
    
        template_name = 'app/article_list.html'  # 可选的
    
        context_object_name = "article_list"    # 默认context名字
    
        paginate_by = 10  # 每页10项

    此时模板article_list.html也需要做出相应调整,如下图所示。Django会先对是否分页is_paginated做个判断,如果有,就会自动生成个page_obj分页对象传递到模板。

    {% if article_list %}
    
        {% for article in article_list %}
    
        {{ article.title }}
    
        {% endfor %}
    
     
    
        {% if is_paginated %}
    
        <ul class="pagination">
    
        {% if page_obj.has_previous %}
    
        <li>
    
            <span><a href="?page={{ page_obj.previous_page_number }}">Previous</a></span>
    
        </li>
    
        {% endif %}
    
        <li class="">
    
            <span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span>
    
        </li>
    
        {% if page_obj.has_next %}
    
              <li>
    
            <span><a href="?page={{ page_obj.next_page_number }}">Next</a></span>
    
        </li>
    
        {% endif %}
    
        </ul>
    
     
    
    {% else %}
    
        <h3>Articles</h3>
    
        <p>No article yet</p>
    
    {% endif %}
  • 相关阅读:
    Making Pimpl Easy
    OpenCV学习资源
    openCV基础学习(1)
    fl2440原始linux代码的启动日志
    《s3c2440+lan91c111 vxworks驱动调试》疑惑
    使用并行的方法计算斐波那契数列 (Fibonacci)
    [译] SolidWorks的发展历史(1994~2007)
    翻译介绍一点CAD发展的历史
    使用fopen的两点注意事项
    四元数(Quaternions)简介
  • 原文地址:https://www.cnblogs.com/Niuxingyu/p/10415313.html
Copyright © 2020-2023  润新知