什么是中间件?
在django中就是一个写了特定方法的类,能在全局范围内改变django的输入和输出。位于web服务层和路由之间。
(中间件是一个全局钩子)
自定义中间件
一.定义与注册
1.定义
创建一个middlewares文件夹,创建一个my_middleware的py文件:
from django.utils.deprecation import MiddlewareMixin
class middle1(MiddlewareMixin):
def process_request(self,request):
...
def process_view(self,request,view_func,view_args,view_kwargs):
...
def process_response(self,request,resposne):
...
2.注册
在settings.py文件中:
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',
'app01'.'middlewares'.'my_middleware'
]
二.middleware中5种方法
这5中方法中处理的HttpRequest和HttpResponse对象是同一个
1.process_request(self,request)
执行时间 | 在web服务端封装好HttpRequest对象后 |
执行顺序 | 按照注册顺序正向执行 |
返回值 | None,正常流程 HttpResponse对象,接下来会去执行该中间件对应的process_response方法,然后继续执行 |
2.process_response(self,request,response)
执行时间 | 视图函数执行之后 |
执行顺序 | 按照注册顺序反向执行 |
返回值 | 必须是HttpResponse对象 |
3.process_view(self,view_func,view_args,view_kwargs)
执行时间 | 路由匹配之后,视图函数执行之前 |
执行顺序 | 按照注册顺序正向执行 |
返回值 | None,正常流程 HttpResponse对象,后边的process_view和视图函数都不执行,开始从最后一个中间件的process_response执行,后面正常 |
4.process_exception(self,request,exception)
执行时间 | 视图函数发生异常之后 |
执行顺序 | 按照注册顺序反向执行 |
返回值 | 可以是None,也是以是HttpResponse对象 |
5.process_template_respone(self,request,respose)
执行时间 | 视图函数的返回值中有render方法,process_process方法执行之前 |
执行顺序 | 按照注册顺序反向执行 |
返回值 | HttpResponse对象 |
三.基于中间件的登录
要求:
1.MD1中间件注册后,所有的请求都要走MD1的process_request方法。
2.如果URL在黑名单中,则返回This is an illegal URL的字符串;
3.访问的URL在白名单内或者session中有user用户名,则不做阻拦走正常流程;
4.正常的URL但是需要登录后访问,让浏览器跳转到登录页面。
简单实现一下:
MD.py(存放中间件)
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,render,redirect
black_url = ["publisher","book","author"] #随便写几个黑名单url
white_url = ["student","teacher","classes"] #随便写几个白名单url
class AuthMD(MiddlewareMixin):
def process_request(self,request):
if request.path_info.strip("/") in black_url: #在黑名单内直接返回
return HttpResponse("This is an illegal URL")
def process_view(self,request,view_func,view_args,view_kwargs):
if request.path_info.strip("/") in white_url: #在白名单内不做拦截
ret = view_func(request)
return ret
def process_response(self,request,response):
return response
views.py
def is_valid(func):
def inner(request,*args,**kwargs):
is_valid = request.session.get("is_login")
if is_valid:
ret = func(request,*args,**kwargs)
return ret
else:
return_url = request.path_info.strip("/")
return redirect("/login/?return_url={}".format(return_url))
return inner
def login(request):
if request.method == "POST":
user = request.POST.get("user")
password = request.POST.get("password")
return_url = request.GET.get("return_url")
if return_url:
if user == "alex" and password == "123":
request.session["is_login"] = 1
return redirect("/{}/".format(return_url))
else:
return redirect("/home/")
return render(request,"login.html")
@is_valid
def index(request):
return HttpResponse("index")
@is_valid
def home(request):
return HttpResponse("home")
def publisher(request):
return HttpResponse("publisher")
def book(request):
return HttpResponse("book")
def author(request):
return HttpResponse("author")
def student(request):
return HttpResponse("student")
def classes(request):
return HttpResponse("classes")
def teacher(request):
return HttpResponse("teacher")