day20-自定义分页
一、前言
我们知道后端数据库里面的数据需要往前端放,之前我们都是很少一部分数据,那如果我们的数据多了怎么办,比如说有1000条,或者10000条以上的数据,那怎么办呐?那我们是不是需要对这些数据做一下分页,然后又多少数据,我们根据这些数据,我们分成多少页,这个是我们经常看到的,所以我们今天就来学习一下自定义分页的功能。
二、自定义分页
2.1、urls.py的代码
说明:先创建url,通过project.urls.py创建url
from django.urls import path from app01 import views urlpatterns = [ path('user_list/',views.user_list) ]
三、在前端实现方式
3.1、views.user_list代码实现
说明:思路就是获取当前页,然后获取切片的开始值和结束值
li = list() for i in range(100): li.append(i) def user_list(request): # data = li[0:10] # data = li[10:20] current_page = request.GET.get("p",1) #获取当前页,没有就默认是第1页 current_page = int(current_page) start = (current_page-1) * 10 #开始位置 end = current_page * 10 #结束位置 data = li[start:end] #获取当前页的数据列表 return render(request,'user_list.html',{'li':data})
3.2、templates的user_list.html的代码:
<body> <ul> {% for item in li %} <li>{{ item }}</li> {% endfor %} </ul> <div> <a href="/user_list/?p=1">1</a> <a href="/user_list/?p=2">2</a> <a href="/user_list/?p=3">3</a> </div> </body>
效果图:
四、后端实现方式
4.1、views.user_list代码实现
说明:利用取模的方式,来判定页数
li = list() for i in range(100): li.append(i) def user_list(request): current_page = request.GET.get("p",1) current_page = int(current_page) start = (current_page-1) * 10 end = current_page * 10 data = li[start:end] #获取总页数 all_count = len(li) count,y = divmod(all_count,10) #返回商和余数,商是页数,余数是是否有最后一页 if y: count += 1 page_list = list() #利用后端往前端放 for i in range(1,count+1): if i== current_page: #判断是否是当前页 temp = '<a class="page active" href="/user_list/?p=%s">%s</a>'%(i,i) else: temp = '<a class="page" href="/user_list/?p=%s">%s</a>'%(i,i) page_list.append(temp) page_str = ''.join(page_list) #拼凑 from django.utils.safestring import mark_safe page_str = mark_safe(page_str) #防止xss攻击,否则前端不识别html return render(request,'user_list.html',{'li':data,'page_str':page_str})
4.2、templates的user_list.html的代码:
<head> <style> .pagination .page{ display: inline-block; padding: 5px; background-color: cyan; } .pagination .page.active{ background-color: brown; color: white; } </style> </head> <body> <ul> {% for item in li %} <li>{{ item }}</li> {% endfor %} </ul> <div class="pagination"> {{ page_str }} </div> </body>
效果如图:
五、xss攻击
在上面的view.user_list的代码发现这么一小段代码:
from django.utils.safestring import mark_safe page_str = mark_safe(page_str) #防止xss攻击,否则前端不识别html
这边有的同学就有疑问了,那我把这段代码去掉如何呢?就是直接把代码放到前端,那我们看view.user_list设置为这样的代码:
def user_list(request): current_page = request.GET.get("p",1) current_page = int(current_page) start = (current_page-1) * 10 end = current_page * 10 data = li[start:end] #从后端往前端放,直接把html的文本放到前端去 page_str = """ <a href="/user_list/?p=1">1</a> <a href="/user_list/?p=2">2</a> <a href="/user_list/?p=3">3</a> """ return render(request,'user_list.html',{'li':data,'page_str':page_str})
templates的user_list.html的代码:
<body> <ul> {% for item in li %} <li>{{ item }}</li> {% endfor %} </ul> <div> {{ page_str }} #直接拿后端发过来的代码 </div> </body>
效果如图:
看到了吧?这边没有解析,那这个是为什么呢?
答:这边就要谈到XSS攻击了,就是说,在默认情况下,django认为所有的在页面上显示的字符串,都是不合法的,如果说这里边你想让它显示,你得说这是安全的,我让它显示,它才能显示,前端需要加上safe,后端需要经过make_safe处理。很多情况下,如果我们默认它安全的话,那如果有人瘫痪你的网站轻而易举,比如说,我在你的评论去输入一个死循环的script,那每次有人点进去就会进入一个死循环,当然这是一个最简单的攻击,还有其他攻击等等。
如何解决呐?这边有两种方式:
①前端通过safe处理
{{ page_str|safe }}
②通过后端make_safe处理,前端就不要动了
#后端 from django.utils.safestring import mark_safe page_str = mark_safe(page_str) #防止xss攻击,否则前端不识别html #前端 {{ page_str }} #正常取值