Django之中间件
1、django 的请求生命周期

说明:
1. wsgiref是django自带的模块,但由于效率低,一般使用的是uwsgi模块,同时使用nignx做负载均衡。
2、中间件
官方解释:中间件是一个用来处理django的请求和响应的框架级别的钩子,它是一个轻量、低级别的插件系统,用于在全局范围内改变django的输入输出。每个中间件组件都负责特定的功能
2.1 django 中间件
默认7个中间件,在settings.py文件下的MIDDLEWARE列表中
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', ]
执行顺序:请求来后,按照上面的顺序从上到下一个一个执行中间件,返回时,从下到上
2.2 中间件中方法
django 中间件可以定义的方法有5个:
process_request(self,request) process_view(self, request, view_func, view_args, view_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response) # 说明:以上方法都可返回None和HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。
1. process_request
语法:process_request(self, request)
参数:request和视图函数的request是一样的。在交给Django后面的路由之前,对这个request对象可以进行一系列的操作。
执行时间:请求到达每个中间件时,第一个执行process_request.
2. process_response
语法:process_response(self, request, response)
参数:
request和视图函数的request是一样的。
response是视图函数返回的HttpResponse对象。该方法必须要有返回值,也必须是HttpResponse对象。如果不返回response而返回其他对象,则浏览器不能正常显示html文件
执行时间:经过view.py返回数据时,从下到上,到达每个中间件,执行该方法
3. process_view
语法:process_view(self, request,view_func,view_args,view_kwargs)
参数:
request是HttpRequest对象。
view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)
view_args是将传递给视图的位置参数的列表.
view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)
执行时间:从上到下执行完每个中间件的process_request后,执行urls.py路由分发,再调头,还是从上到下执行每个中间件的process_view方法。
4. process_exception
语法:process_exception(self, request, exception)
参数:
request是HttpRequest对象
exception是视图函数异常产生的Exception对象。
执行时间:只有在视图函数出现异常时执行,从下到上执行每个中间件的该方法。
5. process_template__response
语法:process_template_response(self, request, response)
参数:
request和视图函数的request是一样的。
response是视图函数返回的HttpResponse对象。该方法必须要有返回值,也必须是HttpResponse对象。
执行时间:该方法只有在视图函数返回中有自定义的render方法时才执行。从下到上执行每个中间件的process_template_response方法。
class MyRender(): def __init__(self, request, msg): self.request = request self.msg = msg def render(self): return HttpResponse(self.msg) def index(request): print(" This is index...") return MyRender(request,"This is index...")
2.3 中间件执行过程

说明:
1. 中间件M1、M2、M3的顺序MIDDLEWARE = ['M1', "M2", "M3"]
2. 红色1,2,3分别代表:如果该函数有返回值一个HttpResponse对象时,走的(”捷径“)路线
3. exception和template_response 不会同时执行
2.4 自定义中间件
1、在项目下创建文件夹mymiddleware,名字任意
2、添加py文件,my_middleware.py
3. 导入父类,from django.utils.deprecation import MiddlewareMixin
4. 在文件中添加中间件
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self, request): print("M1的 reuqest") def process_response(self, request, response): print("M1 的response") return response def process_view(self, request,view_func,view_args,view_kwargs): print("M1 的 view") def process_exception(self, request, exception): print("M1 的 exception") def process_template_response(self, request, response): print("M1 的 template_response") return response
5. 在settings.py 的MIDDLEWARE中注册
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', "mymiddleware.my_middleware.M1", ]
3、示例:使用中间件做登陆验证
def login(request): """中间件对用户登录验证""" if request.method == "GET": return render(request, "login.html") else: name = request.POST.get("name") pwd = request.POST.get("pwd") if name == "sun" and pwd == "123": request.session["login"] = "OK" return_url = request.GET.get("returnURL") print(request.GET) return redirect(return_url or "/home/") else: return HttpResponse("用户名或密码错误") def index(request): """只有登录后才能查看""" return HttpResponse("This is index....") def home(request): """只有登录后才能查看""" return HttpResponse("This is home....")
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse, redirect class LoginAuth(MiddlewareMixin): def process_request(self, request): return_url = request.path #type:str if not return_url.startswith("/login"): if not request.session.get("login", ""): return redirect("/login/?returnURL=%s"%return_url)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap3/css/bootstrap.min.css" /> <script src="/static/bootstrap3/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row col-sm-8 col-sm-offset-2"> <form class="form-horizontal" method="post" action=""> <div class="form-group"> <label for="inputname" class="col-sm-2 control-label"> 用户名 </label> <div class="col-sm-9"> <input type="text" class="form-control" id="inputname" placeholder="用户姓名" name="name"> </div> </div> <div class="form-group"> <label for="inputpwd" class="col-sm-2 control-label"> 密码 </label> <div class="col-sm-9"> <input type="text" class="form-control" id="inputpwd" placeholder="用户密码" name="pwd"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-9"> <button type="submit" class="btn btn-primary">登录</button> </div> </div> </form> </div> </div> </body> </html>

浙公网安备 33010602011771号