发布于2019-09-24 15:24 阅读(1421) 评论(0) 点赞(26) 收藏(0)
from django.core.paginator import Paginator # 导入模块
objects = ['john', 'paul', 'george', 'ringo']
p = Paginator(objects, 2) # 实例化对象 Paginator(对象, 每页放多少数据)
>>> p.count # 获取总的数据有多少条
4
>>> p.num_pages # 总的有多少页
>>> p .range() # 页面范围
>>> type(p.page_range) # 获取总的页码范围
<class 'range_iterator'>
>>> p.page_range
range(1, 3)
>>> page1 = p.page(1) # 获取第1页 对象
>>> page1
<Page 1 of 2>
>>> page1.object_list # 获取第1页的所有数据
['john', 'paul']
>>> page2 = p.page(2) # 获取第2页 对象
>>> page2.object_list
['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() # The 1-based index of the first item on this page
3
>>> page2.end_index() # The 1-based index of the last item on this page
4
from django.shortcuts import render
from django.core.paginator import Paginator
from mydatabase.models import Student
def paginator(request):
"""
要实现分页功能在views视图函数中只需要获取到:
1. 前端传来的每页显示多少条数据per_page
2. 前端传来的当前页page
3. Paginator的数据实例对象paginator
4. 数据的总页数total_page
5. 当前页的数据obj_data
当获取到这几个数据后就可以实现页面显示每页数据条数和页码关联的功能了
"""
-- 获取到分页paginator 对象
1. 从数据库中拿取数据
data_obj = Student.objects.all()/filter(条件).order_by("-create_time") #按照添加时间反向排序
2. 获取前端传来的每页放多少条数据per_page,同时设置一个默认值防止报错
per_page = request.GET.get('per_page',10)
3. 实例化paginator对象
paginator = Paginator(data_obj , per_page)
-- 获取到总的页数
total_page = paginator.num_pages
-- 获取到当前页的数据
1. 获取前端传来的当前页page,同时设置一个默认值防止报错
page = request.GET.get("page", 1)
2. 获取到当前页的数据
obj_data = paginator.paginator.get_page(page)
return render(request,'pagintor.html',
context={
"obj_data ": obj_data,
"per_page": per_page,
"page": page,
"total_page": total_page,
})
这里采用页码当前页+前面页码和后面页码两部分来分析页码显示情况:
同时采用自定义pagination标签:
from django import template
@register.inclusion_tag("self_pagination.html", takes_context=True)
def pagination(context):
"""
根据上面的分析代码情况如下
"""
total_page = context["total_page"] # 获取views传来的总数据
page = int(context["page"]) # 当前页面
num = 3 # 当前页两边各显示多少页码
page_list = [] # 页码显示数列表
# 1 判断当前页+左边部分
# 1.1 当前页小于num时,只有左边
if page-num <= 0:
for i in range(1, page+1):
page_list.append(i)
# 1.2 当前页大于num时,
else:
for i in range(page-num, page+1):
page_list.append(i)
# 2 判断右边部分
# 2.1 当当前页+num大于等于总页数时,只有右边
if page+num >= total_page:
for i in range(page+1, total_page+1):
page_list.append(i)
# 2.2 当前页大于num时,
else:
for i in range(page+1, page+num+1):
page_list.append(i)
return {
"page_list": page_list,
"page": page,
"per_page": context["per_page"],
"total_page": total_page,
}
自定义模板部分:
<div class="btn-group">
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="{% if page > 1 %}{{ request.path }}?per_page={{ per_page }}&page={{ page|add:"-1" }}{% endif %}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% for page_num in page_list %}
<li {% if page_num == page %}class="active"{% endif %}><a href="{{ request.path }}?per_page={{ per_page }}&page={{ page_num }}">{{ page_num }}</a></li>
{% endfor %}
<li>
<a href="{% if page < total_page %}{{ request.path }}?per_page={{ per_page }}&page={{ page|add:"1" }}{% endif %}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
</ul>
</nav>
</div>
<div class="btn-group" style="margin-top: -5px;">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ per_page }}条/页 <span class="caret"></span>
</button>
<ul class="dropdown-menu">
"""
这里设置每页显示数据条数选择可以自己根据需要设置数据
"""
<li><a href="{{ request.path }}?per_page=3">3条/页</a></li>
<li><a href="{{ request.path }}?per_page=5">5条/页</a></li>
<li><a href="{{ request.path }}?per_page=10">10条/页</a></li>
</ul>
</div>
在需要放置分页功能的模板中只需要 {% pagination %}引入我们自定义的包含标签就完成了。
代码汇总:
views视图部分
from django.shortcuts import render
from django.core.paginator import Paginator
from mydatabase.models import Student
def paginator(request):
data_obj = Student.objects.all().order_by('-create_time') # 数据源
per_page = request.GET.get("per_page", 10) # 获取每页数据放几条
paginator = Paginator(data_obj , per_page) # 获取paginator对象
total_page = paginator.num_pages # 获取总的页数
page = request.GET.get("page", 1) # 获取当前页
obj_data = paginator.get_page(page) # 获取当前页数据
return render(request, "pagintor.html",
context={"obj_data ": obj_data ,
"per_page": per_page,
"page": page,
"total_page": total_page,
}
)
自定义pagination标签部分
from django import template
@register.inclusion_tag("self_pagination.html", takes_context=True)
def pagination(context):
"""
根据上面的分析代码情况如下
"""
total_page = context["total_page"] # 获取views传来的总数据
page = int(context["page"]) # 当前页面
num = 3 # 当前页两边各显示多少页码
page_list = [] # 页码显示数列表
# 1 判断当前页+左边部分
# 1.1 当前页小于num时,只有左边
if page-num <= 0:
for i in range(1, page+1):
page_list.append(i)
# 1.2 当前页大于num时,
else:
for i in range(page-num, page+1):
page_list.append(i)
# 2 判断右边部分
# 2.1 当当前页+num大于等于总页数时,只有右边
if page+num >= total_page:
for i in range(page+1, total_page+1):
page_list.append(i)
# 2.2 当前页大于num时,
else:
for i in range(page+1, page+num+1):
page_list.append(i)
return {
"page_list": page_list,
"page": page,
"per_page": context["per_page"],
"total_page": total_page,
}
自定义self_pagination.html模板部分
<div class="btn-group">
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="{% if page > 1 %}{{ request.path }}?per_page={{ per_page }}&page={{ page|add:"-1" }}{% endif %}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% for page_num in page_list %}
<li {% if page_num == page %}class="active"{% endif %}><a href="{{ request.path }}?per_page={{ per_page }}&page={{ page_num }}">{{ page_num }}</a></li>
{% endfor %}
<li>
<a href="{% if page < total_page %}{{ request.path }}?per_page={{ per_page }}&page={{ page|add:"1" }}{% endif %}" aria-label="Next">
<span aria-hidden="true">下一页</span>
</a>
</li>
</ul>
</nav>
</div>
<div class="btn-group" style="margin-top: -5px;">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ per_page }}条/页 <span class="caret"></span>
</button>
<ul class="dropdown-menu">
"""
这里设置每页显示数据条数选择可以自己根据需要设置数据
"""
<li><a href="{{ request.path }}?per_page=3">3条/页</a></li>
<li><a href="{{ request.path }}?per_page=5">5条/页</a></li>
<li><a href="{{ request.path }}?per_page=10">10条/页</a></li>
</ul>
</div>
需要使用分页功能的模板部分
# 循环拿到的数据
<table>
<thead>
<tr>
<th>序号</th>
<th>名字</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ obj_data.name}}</td>
</tr>
</tbody>
</table>
{% pagination %} # 引入分页功能
方式1的分页功能就算实现了
这里将分页功能和每页显示多少条数据显示都封装在一起。
class CustomPagination(object):
"""
自定义分页将分页的页码数和每页存放多少数据封装进类中
"""
def __init__(self, current_page, total_page, path, item_page, max_page_num=7, per_page=10):
self.page = int(current_page) # 当前页
self.path = path # 数据访问路径
self.page_number = max_page_num # 页码显示数量
self.per_page = int(per_page) # 每页数据显示多少个
self.total_page = total_page # 总的有多少页
self.item_page = item_page # 每页显示多少选项
@property
def pager_num_range(self):
"""
显示页面个数这里时按照总的需要显示的页码个数情况来分析写的
:return:
"""
page_list = []
# 1. 当总页数小于显示最多的页面page_number时
if self.total_page < self.page_number:
for i in range(1, self.total_page+1):
page_list.append(i)
# 2. 当总页数大于显示最多的页面page_number时
else:
# 2.0 判断一半的最多显示页面为多少
half_page_number = int(self.page_number) // 2
# 2.1 当当前页数<=一半显示页面时,数字显示页面不变
if self.page <= half_page_number:
for i in range(1, self.page_number + 1):
page_list.append(i)
# 2.2 当当前页数大于一半显示页面,并且当前页数+半值<总页面数时,当前页面就一直在中间保持
elif self.page > half_page_number and self.page + half_page_number <= self.total_page:
for i in range(self.page - half_page_number,self.page+half_page_number+1):
page_list.append(i)
# 2.3 当当前页数+半值>页面总数时,数字显示为总页面数减去page_number到总页数
elif (self.page + half_page_number) > self.total_page:
for i in range(self.total_page - self.page_number, self.total_page+ 1):
page_list.append(i)
return page_list
def page_str(self):
"""
生成html字符串
:return:
"""
page_html_list = []
# 前面的包裹div起始
html_div_start = '<div class="btn-group"><nav aria-label="Page navigation"><ul class="pagination">'
page_html_list.append(html_div_start)
# 首页
first_page = '<li><a href="{}?page=1&per_page={}">首页</a></li>'.format(self.path, self.per_page)
page_html_list.append(first_page)
# 上一页的判断
if self.page == 1:
previous_page = '<li><a href="#">上一页</a></li>'
else:
previous_page = '<li><a href="{}?page={}&per_page={}">上一页</a></li>'.format(self.path, self.page-1, self.per_page)
page_html_list.append(previous_page)
# 中间的页码显示
for index in self.pager_num_range:
if index == self.page:
temp = '<li class="active"><a href="{}?page={}&per_page={}">{}</a></li>'.format(self.path,index, self.per_page,index)
else:
temp = '<li><a href="{}?page={}&per_page={}">{}</a></li>'.format(self.path, index, self.per_page, index)
page_html_list.append(temp)
# 尾页的判断
if self.page == self.total_page:
next_page = '<li><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="{}?page={}&per_page={}">下一页</a></li>'.format(self.path, self.page+1, self.per_page)
page_html_list.append(next_page)
# 尾页
last_page = '<li><a href="{}?page={}&per_page={}">尾页</a></li>'.format(self.path, self.page+1, self.total_page)
page_html_list.append(last_page)
# 前面的包裹div结束
html_div_end = '</ul></nav></div>'
page_html_list.append(html_div_end)
# 下拉框div起始
select_div_start = '<div class="btn-group" style="margin-top: -5px;"><button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {}条/页 <span class="caret"></span></button><ul class="dropdown-menu">'.format(self.per_page)
page_html_list.append(select_div_start)
# 每页显示多少条数据
for num in self.item_page:
temp = '<li><a href="{}?per_page={}">{}条/页</a></li>'.format(self.path, num, num)
page_html_list.append(temp)
# 下拉框div结尾
select_div_end = '</ul></div>'
page_html_list.append(select_div_end)
return ''.join(page_html_list)
from django.shortcuts import render
from plugs.custom_paginal import CustomPagination # 导入自定义的分页类
from mydatabase.models import Student
def paginator(request):
data_obj = Student.objects.all().order_by('-create_time') # 数据源
per_page = request.GET.get("per_page", 10) # 获取每页数据放几条
paginator = Paginator(data_obj , per_page) # 获取paginator对象
total_page = paginator.num_pages # 获取总的页数
page = request.GET.get("page", 1) # 获取当前页
obj_data = paginator.get_page(page) # 获取当前页数据
item_page = [1, 2, 5] # 每页显示数据条数列表
path = request.path # 数据跳转地址
custom_pagination = CustomPagination(page, total_page, path, item_page, per_page=per_page) # 实例化自定义分页对象
return render(request, "pagintor.html",
context={"obj_data ": obj_data,
"custom_pagination": custom_pagination,
}
)
# 循环拿到的数据
<table>
<thead>
<tr>
<th>序号</th>
<th>名字</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ obj_data.name}}</td>
</tr>
</tbody>
</table>
{{ custom_pagination.page_str|safe }} # 引入分页功能
作者:23dh
链接:https://www.pythonheidong.com/blog/article/120966/ee9764c8d3a91a707416/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!