这两周了都快没有写东西了,原因是开始上线下课事情也多了好多,作业也多了好多,上一周还在复习高数的期中考试,但是后面期中考试也取消了。而且django中的好多东西也有点麻烦,写起来不是那么容易,那今天就来浅写一下
目录
分页实现
?分页组件的封装
分页功能主要就是利用算法计算出每页的数据,然后利用bootstrap中的样式加上页码,编写底部页码的跳转,最后循环生成html标签并展示出来,最后实现封装。
分页实现
django中实现分页的核心是类似于python应该切片的功能将我们的数据切开
我们也可以用下一条语句实现对数据的计数
models.UserInfo.objects.all()[ : ]
models.UserInfo.objects.all().count()
我们首先需要根据分页的代码,计算出每页的起始数据和结束的数据,我们这里每页想要十条数据,起始值就是就是页数 - 1 再乘以10 结束值就是页数乘以10
根据用户想要的页码根据起始位置和结束位置,这就是分页的核心
?
page = int(request.GET.get('page',1))
page_size=10
plus=5
start = (page - 1) * page_size
end = page * page_size
page_queryset = models.UserInfo.objects.all()[start:end]
之后我们需要利用bootstrap中的样式加上页码,编写出底部需要跳转的页码,底部的页码怎么算,就是用总数据除以你每页的数据,然后让他循环加1,之后我们下面的页码显示的样子应该是,展示他的前五页和后五页,这里当你的页码数没有达到11页和页码数小于5的时候需要分别对待,要不然页码会无限减小和增加
total_count = models.UserInfo.objects.all().count()
total_page_count,div = divmod(total_count, page_size)
if div:
total_page_count += 1
## 数据库中的数据比较少,没有达到十一页
if total_page_count <= 2 * plus + 1:
start_page = 1
end_page = total_page_count
else:
# 当前页<5时
if self.page <= plus:
start_page = 1
end_page = 2 * plus + 1
else:
# 当前页>5
if (page + plus) > total_page_count:
start_page = total_page_count - 2 * plus
end_page = total_page_count
else:
start_page = page - plus
end_page = page + plus
算出来这些以后,我们就可以利用循环和django中的语法,直接将标签写入到html中,如果是当前页可以加上应该样式
page_str_list = []
for i in range(start_page, end_page + 1):
if i == page:
ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i, i)
else:
ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
page_str_list.append(ele)
page_string = mark_safe("".join(page_string_list))
html中
<div class="container">
<ul class="pagination">
{{ page_string }}
</ul>
</div>
我们还可以将这些东西完善一下,加上上一页,下一页,首页,尾页等
page_str_list.append('<li><a href="?page=1">首页</a></li>')
# 上一页
if self.page > 1:
prev = '<li><a href="?page={}">上一页</a></li>'.format(self.page - 1)
else:
prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
page_str_list.append(prev)
# 下一页
if self.page < self.total_page_count:
prev = '<li><a href="?page={}">下一页</a></li>'.format(self.page + 1)
else:
prev = '<li><a href="?page={}">下一页</a></li>'.format(self.total_page_count)
page_str_list.append(prev)
# 尾页
page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(self.total_page_count))
看看最终的结果
?
?
?分页组件的封装
我们上面再视图函数里面编写这些东西岂不是非常麻烦,首页我们可以单独创建一个文件夹,将上面的东西利用类和面向对象进行封装,再视图函数里面直接用它,这样也就相当于我们自己写了一个分页组件供别人和自己使用
视图函数中
from app01.utils.pagination import pagination
queryset = models.UserInfo.objects.all()
page_object = pagination(request,queryset)
context = {"queryset":page_object.page_queryset,
"page_string":page_object.html()
}
return render(request, 'user_list.html',context)
新建文件中
from django.utils.safestring import mark_safe
class pagination(object):
def __init__(self, request, queryset, page_param="page", page_size=10,plus=5):
'''
:param request: 请求的对象
:param queryset: 符合条件的数据(进行分页处理)
:param page_param: 在url中获取分页的参数,例如/?page=
:param page_size: 显示由多少条数据
:param plus: 显示当前页的前后几页
'''
page = request.GET.get(page_param, "1")
if page.isdecimal():
page = int(page)
else:
page = 1
self.page = page
self.page_size = page_size
self.start = (page - 1) * page_size
self.end = page * page_size
self.page_queryset = queryset[self.start:self.end]
total_count = queryset.count()
total_page_count,div = divmod(total_count, page_size)
if div:
total_page_count += 1
self.total_page_count = total_page_count
self.plus = plus
def html(self):
# 计算出,显示当前页的前五页、后五页
# 数据库中的数据比较少,没有达到十一页
if self.total_page_count <= 2 * self.plus + 1:
start_page = 1
end_page = self.total_page_count
else:
# 当前页<5时
if self.page <= self.plus:
start_page = 1
end_page = 2 * self.plus + 1
else:
# 当前页>5
if (self.page + self.plus) > self.total_page_count:
start_page = self.total_page_count - 2 * self.plus
end_page = self.total_page_count
else:
start_page = self.page - self.plus
end_page = self.page + self.plus
page_str_list = []
# 首页
page_str_list.append('<li><a href="?page=1">首页</a></li>')
# 上一页
if self.page > 1:
prev = '<li><a href="?page={}">上一页</a></li>'.format(self.page - 1)
else:
prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
page_str_list.append(prev)
for i in range(start_page, end_page + 1):
if i == self.page:
ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i, i)
else:
ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
page_str_list.append(ele)
# 下一页
if self.page < self.total_page_count:
prev = '<li><a href="?page={}">下一页</a></li>'.format(self.page + 1)
else:
prev = '<li><a href="?page={}">下一页</a></li>'.format(self.total_page_count)
page_str_list.append(prev)
# 尾页
page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(self.total_page_count))
page_string = mark_safe("".join(page_str_list))
return page_string
'''
自定义的分页组件
视图函数中
1.根据自己的情况取筛选子所要的数据
queryset = models.UserInfo.objects.all()
2.实例化分页对象
page_object = pagination(request,queryset)
context = {"queryset":page_object.page_queryset, 分完页的数据
"page_string":page_object.html() 生成页面
}
return render(request, 'user_list.html',context)
在html中
{% for object in queryset%}
{{obj.xxx}}
{%end_pagefor %%}
'''
|