Django 分页

Posted py-peng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django 分页相关的知识,希望对你有一定的参考价值。

介绍

Django为我们提供一个自带的分页功能,完成不复杂的分页完全小菜一碟。

它被放在了:

from django.core.paginator import Paginator

语法

class Paginator:

    def __init__(self, object_list, per_page, orphans=0,
                 allow_empty_first_page=True):
        self.object_list = object_list
        self._check_object_list_is_ordered()
        self.per_page = int(per_page)
        self.orphans = int(orphans)
        self.allow_empty_first_page = allow_empty_first_page
  • object_list    需要分页的对象,一般从数据库取。
  • per_page     每页显示多少条数据。
  • orphans       一般针对最后一页,少于多少条数据,将数据自动附加到前一页。
  • allow_empty_first_page    是否允许第一页为空。
from django.core.paginator import Paginator

objects
= [john,paul,george,ringo,lucy,meiry,checy,wind,flow,rain]
p = Paginator(objects,3) # 3条数据为一页,实例化分页对象 print p.count # 10 对象总共10个元素 print p.num_pages # 4 对象可分4页 print p.page_range # range(1, 5) 对象页的可迭代范围 page1 = p.page(1) # 取对象的第一分页对象 print page1.object_list # 第一分页对象的元素列表 [‘john‘, ‘paul‘, ‘george‘] print page1.number # 第一分页对象的当前页值 1 page2 = p.page(2) # 取对象的第二分页对象 print page2.object_list # 第二分页对象的元素列表 [‘ringo‘, ‘lucy‘, ‘meiry‘] print page2.number # 第二分页对象的当前页码值 2 print page1.has_other_pages() # 除了第一分页对象是否有其它页 True print page2.has_previous() # 第二分页对象是否有前一页 True print page2.has_next() # 第二分页对象是否有下一页 True
print page2.next_page_number() # 第二分页对象下一页码的值 3 print page2.previous_page_number() # 第二分页对象的上一页码值 1
print page2.start_index() # 第二分页对象的元素开始索引 4 print page2.end_index() # 第2分页对象的元素结束索引 6

官网实例

views.py

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
 
def listing(request):
    contact_list = Contacts.objects.all()
    paginator = Paginator(contact_list, 25) # Show 25 contacts per page
 
    page = request.GET.get(page)
    try:
        contacts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        contacts = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        contacts = paginator.page(paginator.num_pages)
 
    return render(request, list.html, {contacts: contacts})

HTML

{% for contact in contacts %}
    {# Each "contact" is a Contact model object. #}
    {{ contact.full_name|upper }}<br />
    ...
{% endfor %}
 
<div class="pagination">
    <span class="step-links">
        {% if contacts.has_previous %}
            <a href="?page={{ contacts.previous_page_number }}">previous</a>
        {% endif %}
 
        <span class="current">
            Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
        </span>
 
        {% if contacts.has_next %}
            <a href="?page={{ contacts.next_page_number }}">next</a>
        {% endif %}
    </span>
</div>

快速使用

接下来,我们自己去模仿一下官网的实例,前端使用了bootstrap。

views.py

from django.shortcuts import render,redirect,HttpResponse
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage

def teacher(request,*args,**kwargs):
    if request.method == "GET":
        page = request.GET.get("page")
        content_list = models.Teacher.objects.all().values("grade","name","grade__caption") # 从数据取数据
        paginator = Paginator(content_list,3) # 实例化对象
        try:
            contents = paginator.page(page) # 根据URL(页数),获取相应的数据
        except PageNotAnInteger: 
            contents = paginator.page(1)
        except EmptyPage:
            contents = paginator.page(paginator.num_pages) # 页码不存在返回最后一页。
        return render(request,"teacher.html",{"contents":contents})

teacher.html

                <ul class="pagination">
                    {% if contents.has_previous %}
                        <li><a href="?page={{ contents.previous_page_number }}">&laquo;</a></li>
                    {% endif %}
{% for content in contents.paginator.page_range %} {% if content == contents.number %}
<li class="active" ><a href="?page={{ content }}">{{ content }}</a></li> {% else %} <li><a href="?page={{ content }}">{{ content }}</a></li> {% endif %} {% endfor %}
{% if contents.has_next %} <li><a href="?page={{ contents.next_page_number }}">&raquo;</a></li> {% endif %} </ul>

技术图片

 

 技术图片

 

自定义

我想让它显示5页页码,那该咋办?

可以使用过滤器进行简单的判断。

views.py

from django.shortcuts import render,redirect,HttpResponse
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage

def teacher(request,*args,**kwargs):
    if request.method == "GET":
        page = request.GET.get("page")
        content_list = models.Teacher.objects.all().values("grade","name","grade__caption") # 从数据取数据
        paginator = Paginator(content_list,3) # 实例化对象
        try:
            contents = paginator.page(page) # 根据URL(页数),获取相应的数据
        except PageNotAnInteger: 
            contents = paginator.page(1)
        except EmptyPage:
            contents = paginator.page(paginator.num_pages) # 页码不存在返回最后一页。
        return render(request,"teacher.html",{"contents":contents})

register.py

from django import template
from django.utils.html import format_html

register = template.Library()

@register.simple_tag
def select_page(curr_page,loop_page,num_pages,display=3):
    offset = abs(curr_page - loop_page)
    if curr_page < display:
        display += display - curr_page
    elif curr_page + display - 1> num_pages:
        display += num_pages - curr_page
        if curr_page == num_pages:
            display += display - 1
    if offset < display:
        if curr_page == loop_page:
            ele = "<li class=‘active‘><a href=?page=%s>%s</a></li>"%(loop_page,loop_page)
        else:
            ele = "<li><a href=?page=%s>%s</a></li>"%(loop_page,loop_page)
        return format_html(ele)
    else:
        return ""

teacher.html

{% load register %}

<ul class="pagination">
                    {% if contents.has_previous %}
                        <li><a href="?page={{ contents.previous_page_number }}">&laquo;</a></li>
                    {% endif %}
                    {% for content in contents.paginator.page_range %}
                        {% select_page contents.number content contents.paginator.num_pages %}
                    {% endfor %}
                    {% if contents.has_next %}
                        <li><a href="?page={{ contents.next_page_number }}">&raquo;</a></li>
                    {% endif %}
                </ul>

技术图片

 

 技术图片

 

 技术图片

过滤器,接受4个参数,其中一个有默认值。

(当前页,循环页,总页,前后显示页面个数=3)

以上是关于Django 分页的主要内容,如果未能解决你的问题,请参考以下文章

django实现分页功能

Django REST框架分页的jQuery代码

modx - 当我在同上片段中使用“&documents =”参数时,分页不起作用

Django—分页器与form组件

在 Django 中为不同视图共享相同的分页代码

Django rest_framewok框架的基本组件