1、导入django类生成对象之后的方法
# 内置分页需要导入django中的类 from django.core.paginator import Paginator paginator = Paginator(user_list,10) # 第一个参数是我们查出来的所有的对象, 第二个参数表示的是每页显示的行数 # 生成一个paginator对象 paginator可以点出如下的方法 # per_page: 每页显示条目的数量(多少行) # count: 总数据的个数 # num_pages: 总页数 # page_range: 总页数的索引范围,eg: (1,10) 表示第1页到第10页 # page: page对象 users = paginator.page(cur_page) # 需要把当前页数传进去 # 生成page对象,page对象有如下的方法 # has_next 是否有下一页 # next_page_number 下一页的页码 # has_previous 是否有上一页 # previous_page_number 上一页的页码 # object_list 分页之后的数据列表QuerySet 列表中套对象 # number 当前页 # paginator paginator对象
2、后端代码
def test(request): # 首先我们需要从前端获取到需要指定的当前页数 cur_page = request.GET.get("cur_page") # 转成int类型 cur_page = int(cur_page) # 查出所有的对象 user_list = models.UserInfo.objects.all() # 内置分页需要导入django中的类 from django.core.paginator import Paginator paginator = Paginator(user_list,10) users = paginator.page(cur_page) # 需要把当前页数传进去 # 然后就可以把page对象(users)传到前台进行操作 return render(requset,"test.html",{"users":users})
3、前端页面分页处理
{#①先把数据生成#} <ul> {% for user in users.object_list %} <li>{{ user.name }}</li> {% endfor %} </ul> {#上一页 需要判断有没有上一页,有了才跳转#} {% if users.has_previous %} <a href="/test2/?cur_page={{ users.previous_page_number }}">上一页</a> {% else %} <a href="#">上一页</a> {% endif %} {#②生成页面编号#} <li> {#users(page对象)没有总共多少页的属性,但是(paginator对象有)#} {% for num in users.paginator.page_range %} <a href="/test2/?cur_page={{ num }}">{{ num }}</a> {% endfor %} </li> {#③生成上一页与下一页#} {% if users.has_next %} <a href="/test2/?cur_page={{ users.next_page_number }}">下一页</a> {% else %} <a href="#"></a> {% endif %}
由于django系统提供的分页功能有限,不能指定显示多少页,也不能定制一些其他东西,
所以我们自定制分页的类:如下
class CustomPage(object): def __init__(self, cur_page, per_page, total, show_page, uri): """ :param cur_page: 当前的页数 :param per_page: 每页的行数 :param total: 数据总行数 :param show_page: 一共显示多少页(分页数量) :param uri: 处理分页数据的uri """ self.per_page = per_page self.show_page = show_page self.uri = uri # 总行数 / 每页的行数 a 表示正数部分 b表示小数部分 a, b = divmod(total, per_page) if b: self.num_pages = a + 1 else: self.num_pages = a # 如果乱拼写页数,或者不写,就让页数为1 if cur_page == None: self.cur_page = 1 try: self.cur_page = int(cur_page) except Exception as e: self.cur_page = 1 # 如果url拼的页数小于1,让页数为1,如果拼的页数大于最大页数,让页数为最大页数 if self.cur_page < 1: self.cur_page = 1 elif self.cur_page > self.num_pages: self.cur_page = self.num_pages def get_begin(self): # 返回当前页开始的索引位置 return (self.cur_page - 1) * self.per_page def get_stop(self): # 返回当前页结束的索引位置 return self.cur_page * self.per_page def page_core(self): # 返回总体分页代码 half = int(self.show_page / 2) # 总页数小于要显示的页数 if self.num_pages <= half * 2 + 1: begin = 1 stop = self.num_pages + 1 else: # 提交的页数小于1 if self.cur_page - 1 < half: begin = 1 stop = 1 + 2 * half + 1 # 提交的页数大于最大的页数 elif self.cur_page + half > self.num_pages: begin = self.num_pages - 2 * half stop = self.num_pages + 1 # 提交正常页数 else: begin = self.cur_page - half stop = self.cur_page + half + 1 stl = [] # 上一页 if self.cur_page <= 1: prev_page = "<li class=‘%s‘><a href =‘#‘ >上一页</a></li>"%("disabled") else: prev_page = "<li><a href =‘%s?cur_page=%s‘ >上一页</a></li>" % (self.uri, self.cur_page - 1) stl.append(prev_page) # 页标 for num in range(begin, stop): if num == self.cur_page: sta = "<li class=‘%s‘><a href = ‘%s?cur_page=%s‘>%s</a></li>" % ("active",self.uri, num, num) else: sta = "<li><a href = ‘%s?cur_page=%s‘>%s</a></li>" % (self.uri, num, num) stl.append(sta) # 下一页 if self.cur_page >= self.num_pages: next_page = "<li class=‘%s‘><a href =‘#‘ >下一页</a></li>"%("disabled") else: next_page = "<li><a href =‘%s?cur_page=%s‘ >下一页</a></li>" % (self.uri, self.cur_page + 1) stl.append(next_page) # 页面导航整体返到外面 stas = ‘ ‘.join(stl) return stas
后端代码
def model_students(request): if not request.COOKIES: return redirect(‘/user_app/login/‘) # 先获得要显示的页数 cur_page = request.GET.get("cur_page") # 获取数据库中数据的总行数 total = models.Students.objects.count() # 调用类产生自定制分页的对象 cpage = CustomPage(cur_page=cur_page,per_page=6,total=total,show_page=4,uri="/student_app/model_students/") # 获得开始显示的页数 begin = cpage.get_begin() # 获得结束显示的页数 stop = cpage.get_stop() # 获得生成的分页代码字符串 page_info = cpage.page_core() # 通过切片找出需要显示的内容 students = models.Students.objects.all()[begin:stop] # 一并传到页面中进行渲染 return render(request, "model_students.html", {"students": students,"page_info":page_info})
前端代码
{% for item in users %} <tr> <td>{{ item.id }}</td> <td>{{ item.name }}</td> </tr> {% endfor %} <ul class="pagination"> {#需要把这xss改成safe 通过管道符 safe,这样插进来的html字符串才能被浏览器解析#} {{ page_info | safe }} </ul>
1、原理
xss攻击为跨站脚本攻击,主要原因是用户输入的内容不可控形式为在别人的评论区,
或者留言板写入js代码并且提交,如果我们不添加防护措施,就会造成,输入的
js代码会被浏览器解析执行,从而让别人获取到我们浏览器中的信息
2、代码
django中是默认有xss保护的,
如果我们想要取消xss保护,通关 管道符 加上 safe
前端接收参数 {{ page_info | safe }}
后端直接传入js代码, 就可以被浏览器解析执行
csrf攻击为跨站伪造攻击
当我们访问了不受信任的网站时,某一个图片或者连接很有可能会将我们
浏览器的一些信息发送到黑客的电脑上,然后他们伪造我们去一些受信任的
网站对我们的账号进行一些操作(可以轻松拿到我们的cookie)
由此可见,普通的cookie验证防护不了这种csrf攻击,因此我们通过服务器给浏览器发送
一个token字符串进行认证
1、开启csrf验证
a. settings中打开注释
‘django.middleware.csrf.CsrfViewMiddleware‘,
b. 前端表单中开启csrf_token
<form action=""> {% csrf_token %} <input type="text"> </form>
如上,我们每次请求时,服务器都会在我们的表单中添加一个隐藏的token
会在我们下一次提交数据时带上这个token,如果和服务器的相同,就说明我们时真用户
2、当我们开启csrf认证后,想要让部分业务逻辑关闭csrf认证
from django.views.decorators.csrf import csrf_exempt # 先导入csrf_exempt @csrf_exempt def test2(request): pass
这样即便开启了全局csrf认证,也能通过装饰器关闭test2的csrf认证
3、当我们关闭csrf认证后,想要让部分业务逻辑开启csrf认证
from django.views.decorators.csrf import csrf_protect # csrf_protect @csrf_protect def test2(request): pass
这样即便关闭了全局csrf认证,也能通过装饰器开启test2的csrf认证
4、CBV装饰器的使用
我们上面演示的都是FBV,如果是CBV
from django.views.decorators.csrf import csrf_protect,csrf_exempt from django.utils.decorators import method_decorator #csrf_protect 表示关闭的全局csrf认证, 开启部分csrf认证 #csrf_exempt 表示开启全局csrf认证, 关闭部分csrf认证 # name 表示只使用于某种提交的方式 @method_decorator(csrf_exempt,name="get") class Test(object): def get(self): pass def post(self): pass
5、ajax提交token的方式
<script> {# 首先我们要获取到token#} {#通过属性选择器找到存放token值的标签 $("input[name=‘csrfmiddlewaretoken‘]") #} csrf_token = $("input[name=‘csrfmiddlewaretoken‘]").val(); $.ajax({ type:"post", url:"/test2/", {#token放在headers中提交过去,并且headers里面的key时固定的#} headers:{"X-CSRFToken":csrf_token}, success:function () { } }) </script>
原文:https://www.cnblogs.com/hesujian/p/11204319.html