Django自定义分页功能的代码和使用方法
代码示例
实际代码量不多,使用方法包含了前端页面的编写方法以及后端视图函数中的编写方法
先看分页模块的代码吧,这里其实也用到了Django自带的Paginator
from django.core.paginator import Paginator
class Mypage(object):
"""
request: 用于获取get请求携带的pid参数。获取当前页码
list: 是一个queryset对象,是数据库表的数据,即分页的原始数据
page_szie: 自定义每一页显示的数据条数,也是根据这个值取计算总页数
page_param: 自定义从前端传过来的get参数
"""
def __init__(self, request, list, page_size=8, page_param="pid"):
pid = request.GET.get(page_param, "1")
if pid.isdecimal():
pid = int(pid)
else:
pid = 1
# 获取当前页和每页显示多少条数据
self.page_size = page_size
# 获取分页之后的分页对象,即按照page_size分页之后的每一页的数据对象
pages = Paginator(list, page_size)
# 获取最大页码
maxpid = pages.num_pages
if maxpid >= 5:
if pid <= 1:
pid = 1
page = pages.page(1)
page_range = range(1, 6)
elif pid >= maxpid:
pid = maxpid
page = pages.page(maxpid)
page_range = range(maxpid - 4, maxpid + 1)
else:
if pid >= maxpid - 2:
page = pages.page(pid)
page_range = range(maxpid - 4, maxpid + 1)
elif pid <= 3:
page = pages.page(pid)
page_range = range(1, 6)
else:
page = pages.page(pid)
page_range = range(pid - 2, pid + 3)
else:
if pid <= 1:
pid = 1
page = pages.page(1)
page_range = range(1, maxpid + 1)
elif pid >= maxpid:
pid = maxpid
page = pages.page(maxpid)
page_range = range(1, maxpid + 1)
else:
page = pages.page(pid)
page_range = range(1, maxpid + 1)
self.maxpid = maxpid
self.pid = pid
self.page = page
self.page_range = page_range
上述代码中我规定了当总页数大于5页时,每页显示5个分页,可以根据实际需要自行修改~
使用方法------分页功能
如果要只带分页功能,使用如下:
视图函数:views.py
from app01.Myutils.mypage import Mypage
def stock_list(request):
list = models.Stock.objects.filter(**data_dict).order_by('-id')
# 继承自定义的分页类,page_size=8,即表示每一页显示8条数据,支持自定义,可以改为page_size=10则表示每页显示10条数据
page_object = Mypage(request, list, page_size=8)
maxpid = page_object.maxpid
pid = page_object.pid
stocks = page_object.page
page_range = page_object.page_range
return render(request, 'stock_list.html', locals())
前端html页面中的页码实现:复制粘贴自己的html页面去就能使用了!
<!--在模板文件中使用示例如下,复制粘贴即可使用,前提是前端页面导入了BootStrap的CSS样式-->
<!-- 页码 -->
<ul class="pagination">
{% if pid == 1 %}
<li><a href="?pid=1">上一页</a></li>
{% for i in page_range %}
{% if pid == i %}
<li class="active"><a href="?pid={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="?pid={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<li><a href="?pid={{ pid|add:1 }}">下一页</a></li>
{% elif pid == maxpid %}
<li><a href="?pid={{ pid|add:-1 }}">上一页</a></li>
{% for i in page_range %}
{% if pid == i %}
<li class="active"><a href="?pid={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="?pid={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<li><a href="?pid={{ maxpid }}">下一页</a></li>
{% else %}
<li><a href="?pid={{ pid|add:-1 }}">上一页</a></li>
{% for i in page_range %}
{% if pid == i %}
<li class="active"><a href="?pid={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="?pid={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<li><a href="?pid={{ pid|add:1 }}">下一页</a></li>
{% endif %}
</ul>
使用方法------分页+搜索功能
如果想要在相同页面加上搜索功能,那么就会遇到一个小bug,就是搜索完了之后,一点击下一页,搜索的关键字就无了,这就尴尬了,只能看到搜索出来的数据的第一页,达不到想要的效果啊!!
其实这个问题有很多种解决办法,其实就是拼接get参数,让url种保留搜索传到后端的关键字即可!
后端视图函数如下,views.py
# 要支持多个字段的搜索的话建议先导入一个Q模块,sn, status, nip都是数据库的字段名。
form django.db.models import Q
def stock_list(request):
kw = request.GET.get('kw', None)
if kw is not None:
list = models.Stock.objects.filter(Q(sn__contains=kw) | Q(status__contains=kw) | Q(nip__contains=kw)).order_by('-id')
else:
kw = ""
data_dict = {}
list = models.Stock.objects.filter(**data_dict).order_by('-id')
page_object = Mypage(request, list, page_size=8)
maxpid = page_object.maxpid
pid = page_object.pid
stocks = page_object.page
page_range = page_object.page_range
return render(request, 'stock_list.html', locals())
前端页面的代码如下:
<!-- 页码 -->
<!-- 其实就是将参数拼接到url中就行了 -->
<ul class="pagination">
{% if pid == 1 %}
<li><a href="?kw={{ kw }}&pid=1">上一页</a></li>
{% for i in page_range %}
{% if pid == i %}
<li class="active"><a href="?kw={{ kw }}&pid={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="?kw={{ kw }}&pid={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<li><a href="?kw={{ kw }}&pid={{ pid|add:1 }}">下一页</a></li>
{% elif pid == maxpid %}
<li><a href="?kw={{ kw }}&pid={{ pid|add:-1 }}">上一页</a></li>
{% for i in page_range %}
{% if pid == i %}
<li class="active"><a href="?kw={{ kw }}&pid={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="?kw={{ kw }}&pid={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<li><a href="?kw={{ kw }}&pid={{ maxpid }}">下一页</a></li>
{% else %}
<li><a href="?kw={{ kw }}&pid={{ pid|add:-1 }}">上一页</a></li>
{% for i in page_range %}
{% if pid == i %}
<li class="active"><a href="?kw={{ kw }}&pid={{ i }}">{{ i }}</a></li>
{% else %}
<li><a href="?kw={{ kw }}&pid={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<li><a href="?kw={{ kw }}&pid={{ pid|add:1 }}">下一页</a></li>
{% endif %}
</ul>
至此分页功能大功告成!!!
如果不是很明白,建议去b站看一下武沛奇老师的视频,老师没有使用Django自带的Paginator组件,而是全都是用了自定义的方法,另外老师处理分页加搜索bug时使用的方法页建议大家学习!!
链接如下:
最新Python的web开发全家桶(django+前端+数据库)