27-django 分页器
Django自带的分页器(paginator)
paginator分页器的使用
>>> from django.core.paginator import Paginator >>> objects = ['john', 'paul', 'george', 'ringo'] >>> p = Paginator(objects, 2) #2代表的是每页放多少数据 >>> p.count #数据总数 4 >>> p.num_pages #总页数 2 >>> type(p.page_range) # `<type 'rangeiterator'>` in Python 2. <class 'range_iterator'> >>> p.page_range #页码的列表 range(1, 3) # =========[1,2] >>> page1 = p.page(1) #第1页的page对象 >>> page1 <Page 1 of 2> >>> page1.object_list #第1页的数据 ['john', 'paul'] >>> page2 = p.page(2) >>> page2.object_list #第2页的数据 ['george', 'ringo'] >>> page2.has_next() #是否有下一页 False >>> page2.has_previous() #是否有上一页 True >>> page2.has_other_pages() #是否有其他页 True >>> page2.next_page_number() #下一页的页码 Traceback (most recent call last): ... EmptyPage: That page contains no results >>> page2.previous_page_number() #上一页的页码 1 >>> page2.start_index() # 本页第一条记录的序数(从1开始) 3 >>> page2.end_index() # 本页最后录一条记录的序数(从1开始) 4 >>> p.page(0) #错误的页,抛出异常 Traceback (most recent call last): ... EmptyPage: That page number is less than 1 >>> p.page(3) #错误的页,抛出异常 Traceback (most recent call last): ... EmptyPage: That page contains no results
实现一个分页效果demo:
Template:
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap.css' %}">
</head>
<body>
<div class="container">
<h4>分页器</h4>
<ul>
{% for book in book_list %}
<li>{{ book.title }} {{ book.price }}</li>
{% endfor %}
</ul>
<ul class="pagination" id="pager">
{% if book_list.has_previous %}
<li class="previous"><a href="/blog/?page={{ book_list.previous_page_number }}">上一页</a></li>
{% else %}
<li class="previous disabled"><a href="#">上一页</a></li>
{% endif %}
{% for num in paginator.page_range %}
{% if num == currentPage %}
<li class="item active"><a href="/blog/?page={{ num }}">{{ num }}</a></li>
{% else %}
<li class="item"><a href="/blog/?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if book_list.has_next %}
<li class="next"><a href="/blog/?page={{ book_list.next_page_number }}">下一页</a></li>
{% else %}
<li class="next disabled"><a href="#">下一页</a></li>
{% endif %}
</ul>
</div>
</body>
</html>
views:
from django.shortcuts import render,HttpResponse
# Create your views here.
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from app01.models import *
def index(request):
'''
批量导入数据:
Booklist=[]
for i in range(100):
Booklist.append(Book(title="book"+str(i),price=30+i*i))
Book.objects.bulk_create(Booklist)
'''
book_list=Book.objects.all()
paginator = Paginator(book_list, 10)
page = request.GET.get('page',1)
currentPage=int(page)
try:
print(page)
book_list = paginator.page(page)
except PageNotAnInteger:
book_list = paginator.page(1)
except EmptyPage:
book_list = paginator.page(paginator.num_pages)
return render(request,"index.html",locals())
改进版1:实现分页只保留固定的页数和被选中页高亮度显示
参考:Django之分页功能
使用自定义标签:
pagetag.py
#! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "wuxiaoyu" # Date: 2017/9/1 from django.utils.html import format_html from django import template register = template.Library() @register.simple_tag() def circle_page(current_page, loop_page): offset = abs(current_page - loop_page) if offset < 3: # page页面与当前页面的差小于这个数的都会显示出来 if current_page == loop_page: page_ele = '<li class="active"><a href="?page=%s">%s</a></li>' % (loop_page, loop_page) else: page_ele = '<li><a href="?page=%s">%s</a></li>' % (loop_page, loop_page) return format_html(page_ele) else: return ''
views.py
from django.shortcuts import render,HttpResponse,redirect from app01.models import * # Create your views here. from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): ''' Booklist = [] for i in range(100): Booklist.append(Book(title="book" + str(i), price=30 + i * i)) Book.objects.bulk_create(Booklist) :param reuest: :return: ''' try: book_list=Book.objects.all() p=Paginator(book_list,5) page=request.GET.get("page") book_list=p.page(page) except PageNotAnInteger: book_list = p.page(1) except EmptyPage: book_list = p.page(p.num_pages) return render(request,"index.html",locals()) def login(request): if request.method=="POST": if 1: obj=HttpResponse("OK") obj.set_cookie("YYY222","2342342343",max_age=200) return obj return render(request,"login.html")
index.html
{% load pagetag %} {% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% static 'dist/css/bootstrap.css'%}"> <script src="{% static 'dist/js/jquery-3.2.1.min.js' %}"></script> <script src="{% static 'dist/js/bootstrap.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-9 col-md-offset-3"> <h4>分页</h4> <ul> {% for book in book_list %} <li>{{ book.title }} {{ book.price }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> {% if book_list.has_previous %} <li><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li> {% else %} <li class="disabled"><a href="#">上一页</a></li> {% endif %} {% for num in p.page_range %} {% circle_page book_list.number num %} {% endfor %} {% if book_list.has_next %} <li><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li> {% else %} <li class="disabled"><a href="#">下一页</a></li> {% endif %} </ul> </nav> </div> </div> </div> </body> </html>
效果:

缺点:翻到第一页的时候,页数有变化,如下

自定义分页终极版(*****重要~)
下面介绍一个通用的分页技巧,已封装好,只需要调用传参数即可。
项目下新建目录utils,目录下新建文件 pagination.py
class Page(object): def __init__(self,current_page,all_count,base_url,per_page=10,pager_page_count=7): """ 分页初始化 :param current_page: 当前页码 :param per_page: 每页显示数据条数 :param base_url: http://127.0.0.1:8000/index.html/?page=17# 中的/index.html/ :param all_count: 数据库中总条数 :param pager_page_count: 页面上最多显示的页码数量 """ self.base_url = base_url self.current_page = int(current_page) self.per_page = per_page self.all_count = all_count self.pager_page_count = pager_page_count pager_count, b = divmod(all_count, per_page) if b != 0: pager_count += 1 self.pager_count = pager_count half_pager_page_count = int(pager_page_count / 2) self.half_pager_page_count = half_pager_page_count @property def start(self): """ 数据获取值起始索引 :return: """ return (self.current_page - 1) * self.per_page @property def end(self): """ 数据获取值结束索引 :return: """ return self.current_page * self.per_page def page_html(self): """ 生成HTML页码 :return: """ # 如果数据总页码pager_count<11 pager_page_count if self.pager_count < self.pager_page_count: pager_start = 1 pager_end = self.pager_count else: # 数据页码已经超过11 # 判断: 如果当前页 <= 5 half_pager_page_count if self.current_page <= self.half_pager_page_count: pager_start = 1 pager_end = self.pager_page_count else: # 如果: 当前页+5 > 总页码 if (self.current_page + self.half_pager_page_count) > self.pager_count: pager_end = self.pager_count pager_start = self.pager_count - self.pager_page_count + 1 else: pager_start = self.current_page - self.half_pager_page_count pager_end = self.current_page + self.half_pager_page_count page_list = [] if self.current_page <= 1: prev = '<li class="disabled"><a href="#">上一页</a></li>' else: prev = '<li><a href="%s?page=%s">上一页</a></li>' % (self.base_url,self.current_page - 1,) page_list.append(prev) for i in range(pager_start, pager_end + 1): if self.current_page == i: tpl = '<li><a class="active" href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,) else: tpl = '<li><a href="%s?page=%s">%s</a></li>' % (self.base_url, i, i,) page_list.append(tpl) if self.current_page >= self.pager_count: nex = '<li class="disabled"><a href="#">下一页</a></li>' else: nex = '<li><a href="%s?page=%s">下一页</a></li>' % (self.base_url, self.current_page + 1,) page_list.append(nex) page_str = "".join(page_list) return page_str
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), ]
views.py
from utils.pagination import Page def index(request): current_page = request.GET.get('page') all_count = models.Book.objects.all().count() # 默认参数:per_page=10,pager_page_count=7,pager_page_count最好是奇数,左右对称 page_obj = Page(current_page, all_count, request.path_info, per_page=6, pager_page_count=7) book_list = models.Book.objects.all()[page_obj.start:page_obj.end] page_str = page_obj.page_html() return render(request, 'index.html', {'book_list': book_list, 'page_str': page_str})
index.html 在需要页码的地方添加如下代码(配置好引用bootstrap和jquery)
<ul class="pagination"> {{ page_str|safe }} </ul>
如下示例:
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% static 'dist/css/bootstrap.css'%}"> <script src="{% static 'dist/js/jquery-3.2.1.min.js' %}"></script> <script src="{% static 'dist/js/bootstrap.js' %}"></script> </head> <body> <div class="container"> <table border="1"> <thead> <tr> <th>ID</th> <th>title</th> <th>price</th> </tr> </thead> <tbody> {% for row in book_list %} <tr> <td>{{ row.id }}</td> <td>{{ row.title }}</td> // 因为modles只定义了这两个字段 <td>{{ row.price }}</td> </tr> {% endfor %} </tbody> </table> <!--添加页码开始--> <ul class="pagination"> {{ page_str|safe }} </ul> <!--添加页码结束--> </div> </body> </html>
效果:

iview分页和后台数据交互
参考:
https://segmentfault.com/a/1190000010392169(这个是基于url不改变的)
http://www.cnblogs.com/landeanfen/p/6054654.html#_label3_9
https://juejin.im/entry/59ba71f76fb9a00a6974d86b(这个是基于url改变的)
做有积累的事~~

浙公网安备 33010602011771号