前言:本文介绍在Django中如何通过前后端代码实现页面自定义分页功能,详细介绍实现原理,并附实现代码。
实现的功能:
1、根据页数,显示分页标签,并限制显示的分页标签最多10个
2、当前页标签颜色高亮,当页数标签多于10个时位于分页标签的中间处
3、实现上一页、下一页、首页、尾页标签功能
4、具有跳转到指定页面功能,按enter或者点击按钮跳转
5、每页显示的行数可定制,行数修改后页数也跟着变更,每页显示行数使用cookie来保存
实现的原理:
1、分页标签先在后台组装好(这里使用a标签),可以页数几个就组装几个分页标签,然后由Django插入到前端的HTML代码中统一发给请求端。
2、当前页标签高亮功能:首先需要知道用户当前页是哪,这从客户端发送过来的请求数据里取得,然后在组装当前页标签内容时,加上特殊的CSS样式,返回给用户,这样在前端看到的当前页标签样式就和其他不同。
3、当前页标签居中:我们这边限制最多只显示10个标签,后台组装页码标签,一般从(当前页码-4)到(当前页码+5)。特殊情况该功能不起作用,例如1、总页数小于等于10页;2、当前页小于5;3、当前页大于总页数-5。
4、每页显示的行数定制功能:首次请求,默认10行,保存在cookie中。点击修改行数自动触发事件,修改客户端中保存行数信息的cookie值,并刷新页面。服务端在收到客户端发送过来信息中,从cookie中取得行数定制信息,按该行数组装分页标签,再返回给前端。
用到的知识点:
后端
1、request.COOKIES.get(key):取得cookie值,设置cookie:HttpResponse/redirect/render().set_cookie.(k,v,...)
2、render(request, 'URL', {k,v}):返回给前端,可以带参数
3、locals():返回当前所有的本地变量字典,存在部分是django模板用不到变量
3、mark_safe:转义,将HTML代码给转换成HTML实体,否则Django插入前端显示的是“HTML代码”
前端
1、获取cookie:$.cookie(k),设置cookie:$.cookie(k,v,{'path':value})
2、刷新页面location.reload(),跳转到指定页面location.href=url
3、$('XX').bind('keypress', function (event){}):绑定事件band,键盘输入事件keypress,键盘输入值event.keyCode,13为enter
4、$('XX').change(function (){}):change有变动自动触发事件,这边用在修改页面显示行数
5、{{ xxx|safe }}:|,过滤器,safe,将HTML代码给转换成HTML实体,防止XXS攻击,功能后后端的mark_safe相同
后端代码:
def query(request):
"""
current_page:当前页码,默认第一页
line_num:每页显示的行数,默认10行
table_line_count:总行数
page_count:总页数
display_page_num_count:显示的页数码标签总个数,默认10个
"""
current_page = int(request.GET.get('p',1))
line_num = int(request.COOKIES.get("per_page_line_num",10))
table_line_count=tablename.objects.count() ####统计表总行数,tablename指数据库中的表,根据实际修改
display_page_num_count=10
####求总页数
a,b=divmod(table_line_count,line_num) ####求除数和余数,例如divmod(5,1)=(1,1)
if b>0:
page_count=a+1
else:
page_count = a
"""
first_page:首页
last_page:尾页
prev_page:上一页
next_page:下一页
first_display_page_num:第一个显示的页码
last_display_page_num:最后一个显示的页码
"""
first_page = "<a href='/query/?p=%s'>%s</a>" % (1, "首页")
last_page = "<a href='/query/?p=%s'>%s</a>" % (page_count, "尾页")
if current_page-1==0:
prev_page="<a href='/query/?p=%s'>%s</a>" % (current_page, "上一页")
else:
prev_page="<a href='/query/?p=%s'>%s</a>" % (current_page-1, "上一页")
if current_page==page_count:
next_page="<a href='/query/?p=%s'>%s</a>" % (current_page, "下一页")
else:
next_page="<a href='/query/?p=%s'>%s</a>" % (current_page+1, "下一页")
page_str=""
page_str+=first_page
page_str+=prev_page
if page_count<=display_page_num_count:
first_display_page_num = 1
last_display_page_num = page_count + 1
else:
# 总页数大于10页(只显示10个页数标签)
# 如果当前页数《=5
# 显示1-10页数标签
# 如果当前页数x》5
# 显示 x-4到x+5页数标签
# 如果当前页数x》总页数-5
# 显示 总页数-9 到总页数之间的标签
if current_page_num<=5:
first_display_page_num=1
last_display_page_num=display_page_num_count
elif 5<current_page_num<=page_count-5:
first_display_page_num=current_page_num-5+1
last_display_page_num=current_page_num+5
else:
first_display_page_num=page_count-5-5+1
last_display_page_num=page_count
for i in range(first_display_page_num, last_display_page_num):
if i == current_page:
page_str += "<a class='active' href='/query/?p=%s'>%s</a>" % (i, i)
else:
page_str += "<a href='/query/?p=%s'>%s</a>" % (i, i)
page_str += next_page
page_str += last_page
page_str = mark_safe(page_str)
response = render(request, 'query.html', locals())
response.set_cookie("per_page_line_num",line_num,path='/query/') ####设置每页显示的行数
return response
前端代码(query.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.pagination {
display: inline-block;
padding-left: 0;
margin: 20px 0;
border-radius: 4px;
}
.pagenumber {
display: inline-block;
padding-left: 0;
margin: 20px 0;
border-radius: 4px;
}
.pagenumber a {
display: inline-block;
padding: 5px;
background-color: #9cc2cb;
}
.pagenumber a.active {
background-color: brown;
color: white;
}
</style>
</head>
<body>
<label>共{{page_count}}页,{{table_line_count}}行,每页显示
<select class="pagination" id="per_page_line_num">
<option>10</option>
<option>30</option>
<option>50</option>
<option>100</option>
</select>
条记录,</label>
<label>前往
<input type='text' style='width:36px'>页
<input type='button' value='GO' onclick="jumpto(this,'/query/?p=')">
</label>
<div class="pagenumber">
{{ page_str|safe }}
<!--{{ page_str }}-->
</div>
<script>
//设置页面显示的行数,每次访问都先从cookie中取得
$(function () {
var v = $.cookie('per_page_line_num');
$('#per_page_line_num').val(v)
});
//修改页面显示行数
$('#per_page_line_num').change(function () {
var v = $('#per_page_line_num').val();
$.cookie('per_page_line_num', v, {'path': '/query/'});
console.log(v);
location.reload();
});
//跳转到指定页面功能函数,鼠标点击按钮触发
function jumpto(ths, url) {
var v = $(ths).siblings().val();
location.href = url + v;
}
//跳转到指定页面功能函数,enter触发
// $('label input[type=text]').keydown(function (event) {
$('label input[type=text]').bind('keypress', function (event) {
// console.log($(this).val(), event.keyCode);
if (event.keyCode == 13) {
var v = $(this).val();
var url = "/query/?p=";
location.href = url + v;
}
});
</script>
</body>
</html>
是全页面刷新,且每页显示数量放在cookie里传给服务端,然后服务端再根据这信息编排页码标签返回给客户端。
网友评论