介绍
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 }}">«</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 }}">»</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 }}">«</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 }}">»</a></li> {% endif %} </ul>
过滤器,接受4个参数,其中一个有默认值。
(当前页,循环页,总页,前后显示页面个数=3)