中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
process_request(self,request)
process_request
在请求从wsgi拿到之后执行response
,不在执行后续的中间件process_request
方法request
都是同一个对象process_view(self, request, view_func, view_args, view_kwargs)
request
是HttpRequest对象
view_func
是视图函数的名字
view_args
是视图函数的位置参数
view_kwargs
是视图函数的关键字参数
Django会在调用视图函数之前调用process_view
方法
process_template_response(self,request,response)
process_template_response
是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()
方法process_exception(self, request, exception)
request
是HttpRequest对象
,exception
是视图函数异常产生的Exception对象process_response(self, request, response)
request
就是请求来的HttpRequest对象
,response
是视图函数返回的HttpResponse对象
。该方法的返回值也必须是HttpResponse对象
process_request
方法,如果process_request
方法返回None
,就继续顺序执行,如果返回值是HttpResponse
对象,就不再执行后续的process_request
方法,而是执行对应中间件的process_response
方法,将HttpResponse
对象返回前端。process_request
方法执行完后,匹配路由,找到要执行的视图函数,在执行视图之前,先执行中间件的process_view
方法,如果process_view
方法返回None
,继续按顺序执行。路由器:
urlpatterns = [
url(r'^login/$', views.login, name='login'),
url(r'^index/$', views.index, name='index'),
]
视图:
from django.shortcuts import render, HttpResponse, redirect
def login(request):
if request.method == 'POST':
user = request.POST.get('user')
password = request.POST.get('password')
if user == 'Tom' and password == '666666':
request.session['user'] = user
return redirect('/app/index/')
return render(request, 'login.html')
def index(request):
return HttpResponse('index')
模版:
<form action="{% url 'app:login' %}" method="post">
{% csrf_token %}
<p>
<label for="user">用户名:</label>
<input type="text" name="user" id="user">
</p>
<p>
<label for="password">密码:</label>
<input type="text" name="password" id="password">
</p>
<input type="submit" value="登录">
</form>
自定义中间件:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect, HttpResponse
class MyMiddle(MiddlewareMixin):
white_list = ['white', ]
black_list = ['black', ]
def process_request(self, request):
next_url = request.GET.get('next_url')
if next_url in self.white_list and request.session.get('user'):
return
elif next_url in self.black_list:
return HttpResponse('这个url是非法的')