Django_分页

时间:2023-03-08 22:25:49

目录

基本语法

示例

简介

Django提供了一个新的类来帮助你管理分页数据,这个类存放在django/core/paginator.py.它可以接收列表、元组或其它可迭代的对象。

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 def validate_number(self, number):
"""Validate the given 1-based page number."""
try:
number = int(number)
except (TypeError, ValueError):
raise PageNotAnInteger(_('That page number is not an integer'))
if number < 1:
raise EmptyPage(_('That page number is less than 1'))
if number > self.num_pages:
if number == 1 and self.allow_empty_first_page:
pass
else:
raise EmptyPage(_('That page contains no results'))
return number def get_page(self, number):
"""
Return a valid page, even if the page argument isn't a number or isn't
in range.
"""
try:
number = self.validate_number(number)
except PageNotAnInteger:
number = 1
except EmptyPage:
number = self.num_pages
return self.page(number) def page(self, number):
"""Return a Page object for the given 1-based page number."""
number = self.validate_number(number)
bottom = (number - 1) * self.per_page
top = bottom + self.per_page
if top + self.orphans >= self.count:
top = self.count
return self._get_page(self.object_list[bottom:top], number, self) def _get_page(self, *args, **kwargs):
"""
Return an instance of a single page. This hook can be used by subclasses to use an alternative to the
standard :cls:`Page` object.
"""
return Page(*args, **kwargs) @cached_property
def count(self):
"""Return the total number of objects, across all pages."""
try:
return self.object_list.count()
except (AttributeError, TypeError):
# AttributeError if object_list has no count() method.
# TypeError if object_list.count() requires arguments
# (i.e. is of type list).
return len(self.object_list) @cached_property
def num_pages(self):
"""Return the total number of pages."""
if self.count == 0 and not self.allow_empty_first_page:
return 0
hits = max(1, self.count - self.orphans)
return int(ceil(hits / float(self.per_page))) @property
def page_range(self):
"""
Return a 1-based range of pages for iterating through within
a template for loop.
"""
return range(1, self.num_pages + 1) def _check_object_list_is_ordered(self):
"""
Warn if self.object_list is unordered (typically a QuerySet).
"""
ordered = getattr(self.object_list, 'ordered', None)
if ordered is not None and not ordered:
obj_list_repr = (
'{} {}'.format(self.object_list.model, self.object_list.__class__.__name__)
if hasattr(self.object_list, 'model')
else '{!r}'.format(self.object_list)
)
warnings.warn(
'Pagination may yield inconsistent results with an unordered '
'object_list: {}.'.format(obj_list_repr),
UnorderedObjectListWarning,
stacklevel=3
)

django.core.paginator源码

基本语法

# -*- coding:utf-8 -*-
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_previous()) # 第一分页对象是否有前一页 False
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

示例

示例1 使用django内置Paginator模块

from django.urls import path,re_path,include
from testpaginator import views urlpatterns = [
re_path("index/",views.Index.as_view()),
]

urls.py

from django.db import models

class Product(models.Model):
name = models.CharField(max_length=64)
price = models.IntegerField() def __str__(self):
return "{}-{}".format(self.name,self.price)

models.py

from django.shortcuts import render
from django.views import View
from . import models
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage
class Index(View):
def get(self,request):
product_obj_list = models.Product.objects.all() paginator = Paginator(product_obj_list,10)
page = request.GET.get("page") try:
product_obj_list_new = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
product_obj_list_new = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
product_obj_list_new = paginator.page(paginator.num_pages) context = {
"product_obj_list":product_obj_list_new
} return render(request,"page.html",context)

views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ol>
{% for product_obj in product_obj_list %}
{# Each "contact" is a Contact model object. #}
<li>{{ product_obj }}</li>
{% endfor %}
</ol> <div class="pagination">
<span class="step-links">
{% if product_obj_list.has_previous %}
<a href="?page={{ product_obj_list.previous_page_number }}">previous</a>
{% endif %} <span class="current">
Page {{ product_obj_list.number }} of {{ product_obj_list.paginator.num_pages }}.
</span> {% if product_obj_list.has_next %}
<a href="?page={{ product_obj_list.next_page_number }}">next</a>
{% endif %}
</span>
</div> </body>
</html>

page.html

Django_分页

示例2 改写Paginator

# -*- coding:utf-8 -*-
from django.core.paginator import Paginator class CustomPaginator(Paginator):
# 使用方法paginator = CustomPaginator(current_page,per_pager_num,obj_list,per_page)
# current_page :: 当前页面
# per_pager_num :: 显示多少个页码
# obj_list :: 对象列表,显示的主体
# per_page :: 每页多少条目 def __init__(self, current_page, per_pager_num, *args, **kwargs):
# per_pager_num 显示的页码数量
self.current_page = int(current_page)
self.per_pager_num = int(per_pager_num)
super(CustomPaginator, self).__init__(*args, **kwargs) def pager_num_range(self):
'''
自定义显示页码数
第一种:总页数小于显示的页码数
第二种:总页数大于显示页数 根据当前页做判断 a 如果当前页大于显示页一半的时候 ,往右移一下
b 如果当前页小于显示页的一半的时候,显示当前的页码数量
第三种:当前页大于总页数
:return:
''' # 第一种:总页数小于显示的页码数
if self.num_pages < self.per_pager_num: # 如果总页数只有10页,而设置了显示20个页码,则按照总页数显示
return range(1, self.num_pages + 1) # 第二种:总页数大于显示页数 根据当前页做判断
half_part = int(self.per_pager_num / 2)
# a 如果当前页大于显示页一半的时候 ,往右移一下
if self.current_page <= half_part:
# 当前页小于显示页码数量的一半时,比如当前页是3,显示20个页码,则显示1-20这些页码
return range(1, self.per_pager_num + 1)
# b 如果当前页小于显示页的一半的时候,显示当前的页码数量
if (self.current_page + half_part) > self.num_pages:
# 当前页大于显示页码数量的一半时,比如当前页是13,显示20个页码,则显示13-10=3 到 13+10=23的这3-23的页码
return range(self.num_pages - self.per_pager_num + 1, self.num_pages + 1) # 第三种:当前页大于总页数,配合EmptyPage使用,则显示最后一页及其往前20个页码
return range(self.current_page - half_part, self.current_page + half_part + 1)

pager.py

from django.shortcuts import render
from django.views import View
from . import models
from .utils.pager import CustomPaginator
from django.core.paginator import PageNotAnInteger,EmptyPage class Index(View):
def get(self,request):
product_obj_list = models.Product.objects.all()
page = request.GET.get("page")
paginator = CustomPaginator(page,20,product_obj_list,10) try:
product_obj_list_new = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
product_obj_list_new = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
product_obj_list_new = paginator.page(paginator.num_pages) context = {
"product_obj_list":product_obj_list_new
} return render(request,"page.html",context)

views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <ol>
{% for product_obj in product_obj_list %}
{# Each "contact" is a Contact model object.#}
<li>{{ product_obj }}</li>
{% endfor %}
</ol> <div class="pagination">
<span class="step-links">
{% if product_obj_list.has_previous %}
<a href="?page={{ product_obj_list.previous_page_number }}">previous</a>
{% endif %} {% for number in product_obj_list.paginator.pager_num_range %}
{% if number == product_obj_list.number %}
<a href="?page={{ number }}" style="font-size: 33px">{{ number }}</a>
{% else %}
<a href="?page={{ number }}" >{{ number }}</a>
{% endif %} {% endfor %} {% if product_obj_list.has_next %}
<a href="?page={{ product_obj_list.next_page_number }}">next</a>
{% endif %}
<span>({{ product_obj_list.number }}/{{ product_obj_list.paginator.num_pages }})</span>
</span>
</div> </body>
</html>

page.html

Django_分页

示例3 自定义pager组件

示例3.1 objs与pager各自单独使用

class PageInfo(object):
def __init__(self,current_page,all_count,base_url,per_page=10,max_show_page=11): self.per_page = per_page
self.all_count = all_count
self._current_page = current_page
self.max_show_page = max_show_page
self.base_url = base_url @property
def actual_current_page(self):
"""
涉及到(<=0,<0<=all_page,>all_page)
:return:
"""
try:
current_page = int(self._current_page)
if current_page > self.all_page:
current_page = self.all_page
elif current_page <= 0:
current_page = 1 except Exception as e:
current_page = 1
return current_page @property
def all_page(self):
all_page, plus = divmod(self.all_count, self.per_page)
if plus:
all_page += 1
return all_page @property
def start(self):
return (self.actual_current_page-1) * self.per_page @property
def end(self):
return self.actual_current_page * self.per_page @property
def pager_range(self):
"""
显示的页码范围
:return: (begin,stop)
"""
half = (self.max_show_page) // 2
# 如果数据总页数 < 11
if self.all_page < self.max_show_page:
begin = 1
stop = self.all_page + 1
# 如果数据总页数 > 11
else:
# 如果当前页 <= 5,永远显示1,11
if self.actual_current_page <= half: begin = 1
stop = self.max_show_page + 1
else:
if self.actual_current_page + half > self.all_page:
# begin = self.actual_current_page - half
begin = self.all_page - self.max_show_page + 1
stop = self.all_page + 1
else:
begin = self.actual_current_page - half
stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self):
# v = '<a href="/custom.html?page=1">1</a>'
# return v
page_list = []
begin, stop = self.pager_range # 上一页按钮
if self.actual_current_page <= 1:
prev = '<li><a href="#">上一页</a></li>'
else:
prev = '<li><a href="{}?page={}">上一页</a></li>'.format(self.base_url,self.actual_current_page-1)
page_list.append(prev) # 页码按钮
for i in range(begin,stop):
if i == self.actual_current_page:
tmp = '<li class="active"><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i)
else:
tmp = '<li><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i)
page_list.append(tmp) # if self.actual_current_page >= self.all_pager:
# after = '<li><a href="#">下一页</a></li>'
# else:
# after = '<li><a href="{}?page={}">下一页</a></li>'.format(self.base_url,self.actual_current_page+1)
# page_list.append(after) # 下一页按钮
if self.actual_current_page >= self.all_page:
after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
start=self.start+1 if self.start<self.all_count else self.all_count,
end=self.end if self.end<self.all_count else self.all_count,
total=self.all_count)
else:
after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
url=self.base_url,
next_page=self.actual_current_page+1,
start=self.start+1 if self.start<self.all_count else self.all_count,
end=self.end if self.end<self.all_count else self.all_count,
total=self.all_count
)
page_list.append(after) return " ".join(page_list)

pager2.py

from .utils.pager2 import PageInfo
from django.shortcuts import render
from django.views import View
from . import models class Index(View):
def get(self,request):
page = request.GET.get("page")
product_obj_list = models.Product.objects.all()
all_count = product_obj_list.count() page_info = PageInfo(page,all_count,"") product_obj_list_new = product_obj_list[page_info.start:page_info.end] context = {
"product_obj_list":product_obj_list_new,
"pager":page_info,
} return render(request,"page.html",context)

views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.min.css">
</head>
<body> <ol>
{% for product_obj in product_obj_list %}
{# Each "contact" is a Contact model object.#}
<li>{{ product_obj }}</li>
{% endfor %}
</ol>
<nav aria-label="Page navigation">
<ul class="pagination">
{{ pager.pager_str|safe }}
</ul>
</nav>
{{ pager.pager_str|safe }} </body>
</html>

page.html

Django_分页

示例3.2 objs封装到pager里

# -*- coding:utf-8 -*-

class PageInfo(object):
def __init__(self,items,current_page,base_url,per_page=10,max_show_page=11):
self._items = items
self.per_page = per_page
self.all_count = self._items.count()
self._current_page = current_page
self.max_show_page = max_show_page
self.base_url = base_url @property
def items(self):
return self._items[self.start:self.end] @property
def actual_current_page(self):
"""
涉及到(<=0,<0<=all_page,>all_page)
:return:
"""
try:
current_page = int(self._current_page)
if current_page > self.all_page:
current_page = self.all_page
elif current_page <= 0:
current_page = 1 except Exception as e:
current_page = 1
return current_page @property
def all_page(self):
all_page, plus = divmod(self.all_count, self.per_page)
if plus:
all_page += 1
return all_page @property
def start(self):
return (self.actual_current_page-1) * self.per_page @property
def end(self):
return self.actual_current_page * self.per_page @property
def pager_range(self):
"""
显示的页码范围
:return: (begin,stop)
"""
half = (self.max_show_page) // 2
# 如果数据总页数 < 11
if self.all_page < self.max_show_page:
begin = 1
stop = self.all_page + 1
# 如果数据总页数 > 11
else:
# 如果当前页 <= 5,永远显示1,11
if self.actual_current_page <= half: begin = 1
stop = self.max_show_page + 1
else:
if self.actual_current_page + half > self.all_page:
# begin = self.actual_current_page - half
begin = self.all_page - self.max_show_page + 1
stop = self.all_page + 1
else:
begin = self.actual_current_page - half
stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self):
# v = '<a href="/custom.html?page=1">1</a>'
# return v
page_list = []
begin, stop = self.pager_range # 上一页按钮
if self.actual_current_page <= 1:
prev = '<li><a href="#">上一页</a></li>'
else:
prev = '<li><a href="{}?page={}">上一页</a></li>'.format(self.base_url,self.actual_current_page-1)
page_list.append(prev) # 页码按钮
for i in range(begin,stop):
if i == self.actual_current_page:
tmp = '<li class="active"><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i)
else:
tmp = '<li><a href="{}?page={}">{}</a></li>'.format(self.base_url,i,i)
page_list.append(tmp) # if self.actual_current_page >= self.all_pager:
# after = '<li><a href="#">下一页</a></li>'
# else:
# after = '<li><a href="{}?page={}">下一页</a></li>'.format(self.base_url,self.actual_current_page+1)
# page_list.append(after) # 下一页按钮
if self.actual_current_page >= self.all_page:
after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
start=self.start+1 if self.start<self.all_count else self.all_count,
end=self.end if self.end<self.all_count else self.all_count,
total=self.all_count)
else:
after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
url=self.base_url,
next_page=self.actual_current_page+1,
start=self.start+1 if self.start<self.all_count else self.all_count,
end=self.end if self.end<self.all_count else self.all_count,
total=self.all_count
)
page_list.append(after) return " ".join(page_list)

pagers.py

from .utils.pager2 import PageInfo
from django.shortcuts import render
from django.views import View
from . import models class Index(View):
def get(self,request):
page = request.GET.get("page")
product_obj_list = models.Product.objects.all()
# all_count = product_obj_list.count() page_info = PageInfo(product_obj_list,page,"") # product_obj_list_new = product_obj_list[page_info.start:page_info.end] # 封装到pager里 context = {
# "product_obj_list":product_obj_list_new,
"pager":page_info,
} return render(request,"page.html",context)

views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.min.css">
</head>
<body> <ol>
{# {% for product_obj in product_obj_list %}#}
{% for product_obj in pager.items %}
{# Each "contact" is a Contact model object.#}
<li>{{ product_obj }}</li>
{% endfor %}
</ol>
<nav aria-label="Page navigation">
<ul class="pagination">
{{ pager.pager_str|safe }}
</ul>
</nav>
{{ pager.pager_str|safe }} </body>
</html>

page.html

Django_分页

示例3.3 增加url里的QueryDict

class PageInfo(object):
def __init__(self,items,current_page,base_url,page_param_dict,per_page=10,max_show_page=11):
self._items = items
self.per_page = per_page
self.all_count = self._items.count()
self._current_page = current_page
self.max_show_page = max_show_page
self.base_url = base_url
self.page_param_dict = page_param_dict @property
def items(self):
return self._items[self.start:self.end] @property
def actual_current_page(self):
"""
涉及到(<=0,<0<=all_page,>all_page)
:return:
"""
try:
current_page = int(self._current_page)
if current_page > self.all_page:
current_page = self.all_page
elif current_page <= 0:
current_page = 1 except Exception as e:
current_page = 1
return current_page @property
def all_page(self):
all_page, plus = divmod(self.all_count, self.per_page)
if plus:
all_page += 1
return all_page @property
def start(self):
return (self.actual_current_page-1) * self.per_page @property
def end(self):
return self.actual_current_page * self.per_page @property
def pager_range(self):
"""
显示的页码范围
:return: (begin,stop)
"""
half = (self.max_show_page) // 2
# 如果数据总页数 < 11
if self.all_page < self.max_show_page:
begin = 1
stop = self.all_page + 1
# 如果数据总页数 > 11
else:
# 如果当前页 <= 5,永远显示1,11
if self.actual_current_page <= half: begin = 1
stop = self.max_show_page + 1
else:
if self.actual_current_page + half > self.all_page:
# begin = self.actual_current_page - half
begin = self.all_page - self.max_show_page + 1
stop = self.all_page + 1
else:
begin = self.actual_current_page - half
stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self):
# v = '<a href="/custom.html?page=1">1</a>'
# return v
page_list = []
begin,stop = self.pager_range # 上一页按钮
if self.actual_current_page <= 1:
prev = '<li><a href="#">上一页</a></li>'
else:
self.page_param_dict["page"] = self.actual_current_page-1
prev = '<li><a href="{}?{}">上一页</a></li>'.format(self.base_url,self.page_param_dict.urlencode()) page_list.append(prev) # 页码按钮
for i in range(begin,stop):
self.page_param_dict["page"] = i
if i == self.actual_current_page:
tmp = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i)
else:
tmp = '<li><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i)
page_list.append(tmp) # 下一页按钮
if self.actual_current_page >= self.all_page:
after = '<li><a href="#">下一页</a></li>'
else:
self.page_param_dict["page"] = self.actual_current_page+1
after = '<li><a href="{}?{}">下一页</a></li>'.format(self.base_url,self.page_param_dict)
page_list.append(after) # if self.actual_current_page >= self.all_pager:
# after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
# start=self.start+1 if self.start<self.all_count else self.all_count,
# end=self.end if self.end<self.all_count else self.all_count,
# total=self.all_count)
# else:
# after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
# url=self.base_url,
# next_page=self.actual_current_page+1,
# start=self.start+1 if self.start<self.all_count else self.all_count,
# end=self.end if self.end<self.all_count else self.all_count,
# total=self.all_count
# )
# page_list.append(after) return " ".join(page_list)

pager2.py

from .utils.pager2 import PageInfo
from django.shortcuts import render
from django.views import View
from . import models
from django.http.request import QueryDict class Index(View):
def get(self,request): product_obj_list = models.Product.objects.all()
page = request.GET.get("page") q = QueryDict(mutable=True) # mutable,可改变的。而request.GET是immutable的。
q.update(request.GET)
page_info = PageInfo(product_obj_list,page,"",q) # product_obj_list_new = product_obj_list[page_info.start:page_info.end] # 把这一段封装到PageInfo里了 context = {
# "product_obj_list":product_obj_list_new,
"pager":page_info,
} return render(request,"page.html",context)

views.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.min.css">
</head>
<body> <ol>
{% for product_obj in pager.items %}
{# Each "contact" is a Contact model object.#}
<li>{{ product_obj }}</li>
{% endfor %}
</ol>
<nav aria-label="Page navigation">
<ul class="pagination">
{{ pager.pager_str|safe }}
</ul>
</nav>
{{ pager.pager_str|safe }} </body>
</html>

page.html

Django_分页

增加首页、末页

class PageInfo(object):
def __init__(self,items,current_page,base_url,page_param_dict,per_page=10,max_show_page=11):
self._items = items
self.per_page = per_page
self.all_count = self._items.count()
self._current_page = current_page
self.max_show_page = max_show_page
self.base_url = base_url
self.page_param_dict = page_param_dict @property
def items(self):
return self._items[self.start:self.end] @property
def actual_current_page(self):
"""
涉及到(<=0,<0<=all_page,>all_page)
:return:
"""
try:
current_page = int(self._current_page)
if current_page > self.all_page:
current_page = self.all_page
elif current_page <= 0:
current_page = 1 except Exception as e:
current_page = 1
return current_page @property
def all_page(self):
all_page, plus = divmod(self.all_count, self.per_page)
if plus:
all_page += 1
return all_page @property
def start(self):
return (self.actual_current_page-1) * self.per_page @property
def end(self):
return self.actual_current_page * self.per_page @property
def pager_range(self):
"""
显示的页码范围
:return: (begin,stop)
"""
half = (self.max_show_page) // 2
# 如果数据总页数 < 11
if self.all_page < self.max_show_page:
begin = 1
stop = self.all_page + 1
# 如果数据总页数 > 11
else:
# 如果当前页 <= 5,永远显示1,11
if self.actual_current_page <= half: begin = 1
stop = self.max_show_page + 1
else:
if self.actual_current_page + half > self.all_page:
# begin = self.actual_current_page - half
begin = self.all_page - self.max_show_page + 1
stop = self.all_page + 1
else:
begin = self.actual_current_page - half
stop = self.actual_current_page + half + 1 return (begin,stop) def pager_str(self):
# v = '<a href="/custom.html?page=1">1</a>'
# return v
page_list = []
begin,stop = self.pager_range # 上一页按钮
if self.actual_current_page <= 1:
prev = '<li><a href="#">上一页</a></li>'
else:
self.page_param_dict["page"] = self.actual_current_page-1
prev = '<li><a href="{}?{}">上一页</a></li>'.format(self.base_url,self.page_param_dict.urlencode()) page_list.append(prev) self.page_param_dict['page'] = 1
first = '<li><a href="%s?%s">首页</a></li>' % (self.base_url,self.page_param_dict.urlencode())
page_list.append(first) # 页码按钮
for i in range(begin,stop):
self.page_param_dict["page"] = i
if i == self.actual_current_page:
tmp = '<li class="active"><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i)
else:
tmp = '<li><a href="{}?{}">{}</a></li>'.format(self.base_url,self.page_param_dict.urlencode(),i)
page_list.append(tmp) self.page_param_dict['page'] = self.all_page
last = '<li><a href="%s?%s">末页</a></li>' % (self.base_url, self.page_param_dict.urlencode())
page_list.append(last) # 下一页按钮
if self.actual_current_page >= self.all_page:
after = '<li><a href="#">下一页</a></li>'
else:
self.page_param_dict["page"] = self.actual_current_page+1
after = '<li><a href="{}?{}">下一页</a></li>'.format(self.base_url,self.page_param_dict)
page_list.append(after) # if self.actual_current_page >= self.all_pager:
# after = '<li><a href="#">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
# start=self.start+1 if self.start<self.all_count else self.all_count,
# end=self.end if self.end<self.all_count else self.all_count,
# total=self.all_count)
# else:
# after = '<li><a href="{url}?page={next_page}">下一页</a></li><span>({start}-{end}/共{total})</span>'.format(
# url=self.base_url,
# next_page=self.actual_current_page+1,
# start=self.start+1 if self.start<self.all_count else self.all_count,
# end=self.end if self.end<self.all_count else self.all_count,
# total=self.all_count
# )
# page_list.append(after) return " ".join(page_list)

增加首页、末页

class Page(object):
def __init__(self, current_page, all_count, base_url, query_params, per_page=10, pager_page_count=11):
"""
分页初始化
:param current_page: 当前页码
:param per_page: 每页显示数据条数
:param all_count: 数据库中总条数
:param pager_page_count: 页面上最多显示的页码数量
"""
self.base_url = base_url
self.query_params = query_params
try:
self.current_page = int(current_page)
if self.current_page <= 0:
raise Exception()
except Exception as e:
self.current_page = 1 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><a href="#">上一页</a></li>'
else:
self.query_params['page'] = self.current_page - 1
prev = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url,self.query_params.urlencode())
page_list.append(prev) self.query_params['page'] = 1
first = '<li><a href="%s?%s">首页</a></li>' % (self.base_url,self.query_params.urlencode())
page_list.append(first) for i in range(pager_start, pager_end + 1):
self.query_params['page'] = i
if self.current_page == i:
tpl = '<li class="active"><a href="%s?%s">%s</a></li>' % (
self.base_url, self.query_params.urlencode(), i,)
else:
tpl = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.query_params.urlencode(), i,)
page_list.append(tpl) self.query_params['page'] = self.pager_count
last = '<li><a href="%s?%s">末页</a></li>' % (self.base_url, self.query_params.urlencode())
page_list.append(last) if self.current_page >= self.pager_count:
nex = '<li><a href="#">下一页</a></li>'
else:
self.query_params['page'] = self.current_page + 1
nex = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode(),)
page_list.append(nex)
page_str = "".join(page_list)
return page_str

增加首页、末页,无items

参考or转发

https://www.cnblogs.com/kongzhagen/p/6640975.html

https://www.cnblogs.com/nulige/p/6558207.html