[TOC]css
在前面的博客中已经学会了给视图函数加装饰器来判断是用户是否登陆,把没有登陆的用户请求跳转到登陆页面。咱们经过给几个特定视图函数加装饰器实现了这个需求。可是之后添加的视图函数可能也须要加上装饰器,这样是否是稍微有点繁琐。
他就像至关于django的门户,通俗一点就是阻止你进门的保安,须要验证。
只要是全局相关的功能你都应该考虑使用django中间件来帮你完成html
全局用户身份校验 全局用户访问频率校验 用户访问黑名单 用户访问白名单
什么是中间件:python
中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每一个中间件组件都负责作一些特定的功能。
中间件是帮助咱们在视图函数执行以前和执行以后均可以作一些额外的操做,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。
注意:jquery
可是因为其影响的是全局,因此须要谨慎使用,使用不当会影响性能。
只要之后用django开发业务 设计到全局相关的功能 你就考虑用中间件ajax
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
中间件能够定义六个方法,分别是:(主要的是process_request和process_response)django
class SessionMiddleware(MiddlewareMixin): def process_request(self, request): def process_response(self, request, response): class CsrfViewMiddleware(MiddlewareMixin): def process_request(self, request): def process_view(self, request, callback, callback_args, callback_kwargs): def process_response(self, request, response): class AuthenticationMiddleware(MiddlewareMixin): def process_request(self, request):
以上方法的返回值能够是None或一个HttpResponse对象,若是是None,则继续按照django定义的规则向后继续执行,若是是HttpResponse对象,则直接将该对象返回给用户
请求来的时候会按照配置文件中注册的中间从上往下的顺序依次执行每个中间件里的process_request方法,若是没有直接跳过执行下一个同级别返回,并不会所有执行process_resquest
process_request有一个参数,就是request,这个request和视图函数中的request是同样的 因为request对象是同样的,因此咱们能够对request对象进行一系列的操做,包括request.变量名=变量值,这样的操做,咱们能够在后续的视图函数中经过相同的方式便可获取到咱们在中间件中设置的值。
它的返回值能够是None也能够是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,若是是HttpResponse对象,Django将不执行视图函数,而将相应对象返回给浏览器。
代码:bootstrap
相应走的时候会按照配置文件中注册的中间件从下往上的顺序依次执行每个中间件里面的process_response方法,该方法必需要有两个形参,而且须要将形参respondse返回 若是你内部本身返回了HttpResponse对象 会将返回给用户浏览器的内容替换成你本身的
路人匹配成功执行视图函数以前触发
process_view(self, request, view_func, view_args, view_kwargs) 该方法有四个参数 request是HttpRequest对象。 view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称做为字符串。) view_args是将传递给视图的位置参数的列表. view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。 Django会在调用视图函数以前调用process_view方法。
它应该返回None或一个HttpResponse对象。 若是返回None,Django将继续处理这个请求,执行任何其余中间件的process_view方法,而后在执行相应的视图。 若是它返回一个HttpResponse对象,那么将不会执行Django的视图函数,而是直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器
视图函数返回的对象中必需要有render属性对应的render方法
视图函数返回的对象中必需要有render属性对应的render方法 def index(request): print('我是视图函数index') def render(): return HttpResponse("你好啊 我是index里面的render函数") obj = HttpResponse("index") obj.render = render return obj
当视图函数报错的时候自动触发
该方法两个参数: 一个HttpRequest对象 一个exception是视图函数异常产生的Exception对象 这个方法只有在视图函数中出现异常了才执行,它返回的值能够是一个None也能够是一个HttpResponse对象。若是是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,不然将默认处理异常。若是返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。
本质搭建一个跟正常网站如出一辙的页面 用户在该页面上完成转帐功能 转帐的请求确实是朝着正常网站的服务端提交 惟一不一样的在于收款帐户人不一样 给用户书写form表单 对方帐户的input没有name属性 你本身悄悄提早写好了一个具备默认的而且是隐藏的具备name属性的input 模拟钓鱼网站
要作一个网站跟他同样
效果:给用户转的钱到钓鱼网站的用户帐上去了
浏览器
解决钓鱼网站问题:session
form表单如何经过csrf校验 你只须要在你的form表单内写一个 {% csrf_token %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <h2>我是正儿八经的网站</h2> <form action="" method="post"> {# {% csrf_token %}#} <p>username:<input type="text" name="username"></p> <p>target_user:<input type="text" name="target_user"></p> <p>money:<input type="text" name="money"></p> <input type="submit"> </form> <button id="d1">发送ajax请求</button> {#{% load static %}#} {#<script src="{% static 'myset.js' %}"></script>#} {#<script>#} {# $('#d1').click(function () {#} {# $.ajax({#} {# url:'',#} {# type:'post',#} {#data:{'username':'jason'},#} {# // 第一种方式 本身手动获取#} {#data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#} {# // 第二种方式 利用模板语法#} {#data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#} {# // 第三种 通用方式 引入外部js文件#} {# data:{'username':'jason'},#} {# success:function (data) {#} {# alert(data)#} {# }#} {# })#} {# })#} {#</script>#} </body> </html>
// 第一种方式 本身手动获取 {#data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#} // 第二种方式 利用模板语法 {#data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#} // 第三种 通用方式 引入外部js文件 官网提供的方式 {% load static %} <script src="{% static 'myset.js' %}"></script> data:{'username':'jason'}
当咱们网站总体都校验csrf的时候 我想让某几个视图函数不校验 当咱们网站总体都不校验csrf的时候 我想让某几个视图函数校验
给CBV加装饰器 推荐你使用模块method_decorator 咱们本身写的装饰器和csrf_protect用法一致 惟独csrf_exempt是一个特例 只能给dispatch方法装
导入:框架
from django.views.decorators.csrf import csrf_exempt, csrf_protect from django.views import View9 from django.utils.decorators import method_decorator
# @method_decorator(csrf_protect,name='post') # 第二种指名道姓的给类中某个方法装 # @method_decorator(csrf_exempt,name='post') # csrf_exempt 第二种方式不行 @method_decorator(csrf_exempt,name='dispatch') # 能够!!! class MyHome(View): # APIView # @method_decorator(csrf_protect) # 第三种 类中全部的方法都装 # @method_decorator(csrf_exempt) # csrf_exempt 第三种方式能够 def dispatch(self, request, *args, **kwargs): return super().dispatch(request,*args,**kwargs) def get(self,request): return HttpResponse('get') # @method_decorator(csrf_protect) # 第一种方式 # @method_decorator(csrf_exempt) # csrf_exempt 第一种方式不行 def post(self,request): return HttpResponse('post')
django用户相关的自带的功能模块 auth_user表
createsuperuser
from django.contrib import auth from django.contrib.auth.models import User
User.objects.create() # 密码是明文 User.objects.createuser() # 基本都用它 User.objects.createsuperuser() # 邮箱要给数据
auth.authenticate(username=username,password=password) # 用户名和密码两个一个都不能少 # 该方法当用户名和密码正确的时候返回的用户对象 不正确返回None
auth.login(request,user_obj) # 这一句执行以后 request.user获取当前登陆的用户对象
request.user.is_authenticated() # 判断是否登陆 request.user # 登陆用户对象
from django.contrib.auth.decorators import login_required # 局部配置 @login_required(login_url='/login/') def xxx(request): return HttpResponse('xxx页面') # 全局配置 配置文件中写如下代码 LOGIN_URL = '/login/' @login_required def xxx(request): return HttpResponse('xxx页面') # 若是两个都设置了 那么优先执行局部配置
request.user.check_password(old_password) # 校验原密码是否正确 request.user.set_password(new_password) request.user.save() # 必定要保存
auth.logout(request)
# 2 利用类的继承 # 1 类的继承 from django.contrib.auth.models import User,AbstractUser # Create your models here. class Userinfo(AbstractUser): phone = models.BigIntegerField() avatar = models.FileField() # 扩展的字段 尽可能不要与原先表中的字段冲突 # 2 配置文件 AUTH_USER_MODEL = '应用名.表名'
总结:
django就会将userinfo表来替换auth_user表 而且以前auth模块全部的功能不变 参照的也是userinfo表