五个方法:
中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
- process_request(self,request)
- process_response(self, request, response)
- process_view(self, request, view_func, view_args, view_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。
自定义中间件:
应用下创建一个文件夹,例如xx文件夹
创建一个python文件,xx.py
From django.utils.deprecation import MiddeWareMixin
Class MyAuth(MiddeWareMixin):
Def 这里就可以写那五个方法,来拦截请求,响应等
流程
请求—wsgi.py—中间件(process_request)—urls.py—视图(数据库:orm,template:html)—中间(process_response)
里面有一个@login_required标签。其作用就是告诉程序,使用这个方法是要求用户登录的。
1.如果用户还没有登录,默认会跳转到‘/accounts/login/’。这个值可以在settings文件中通过LOGIN_URL参数来设定。(后面还会自动加上你请求的url作为登录后跳转的地址,如:/accounts/login/?next=/polls/3/ 登录完成之后,会去请求/poll/3)
2.如果用户登录了,那么该方法就可以正常执行
如果LOGIN_URL使用默认值,那么在urls.py中还需要进行如下设置:(加入下面这句)
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
这样的话,如果未登录,程序会默认跳转到“templates\registration\login.html”这个模板。>
Django 中间件
Django 中间件是修改 Django request 或者 response 对象的钩子,可以理解为是介于 HttpRequest 与 HttpResponse 处理之间的一道处理过程。
浏览器从请求到响应的过程中,Django 需要通过很多中间件来处理,可以看如下图所示:
Django 中间件作用:
修改请求,即传送到 view 中的 HttpRequest 对象。
修改响应,即 view 返回的 HttpResponse 对象。
中间件组件配置在 settings.py 文件的 MIDDLEWARE 选项列表中。
配置中的每个字符串选项都是一个类,也就是一个中间件。
Django 默认的中间件配置:
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(self,request)
- process_response(self, request, response)
- process_view(self, request, view_func, view_args, view_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
自定义中间的步骤:
1.在任意一个位置创建一个文件夹
2.在文件夹中创建一个任意命名的py文件
3.在py文件中创建一个class类,这个类必须继承(MiddeWareMixin)
From django.utils.deprecation import MiddeWareMixin
Class Math(MiddeWareMixin):
Def 这里就可以写那五个方法,来拦截请求,响应等
4.在strings中注册
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。
process_request(self,request)方法
process_request 方法有一个参数 request,这个 request 和视图函数中的 request 是一样的。
process_request 方法的返回值可以是 None 也可以是 HttpResponse 对象。
1.请求来的时候需要经过每一个中间件的process_request方法,是按照配置文件中的注册中间件的从上到下执行的
2.如果中间件中没有定义方法,就直接跳到下一个中间件中
3.如果该方法中间件返回了heepresponse对象那么接下来的请求将不会继续往后执行,而是直接返回
process_request方法主要是用来做全局相关的所有限制功能
实例
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行
process_response(self, request, response)
1.process_response 方法有两个参数,一个是 request,一个是 response,
request 是请求对象,
response 是视图函数返回的 HttpResponse 对象,
2. 该方法必须要有返回值,且必须是response。 HttpResponse 对象,
默认返回的是形参response
也可以返回自己的
3.当配置多个中间件时,会按照 MIDDLEWARE 中的注册顺序,也就是列表的索引值,倒序执行。
4.process_response 方法是在视图函数之后执行的。
实例
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行
def process_response(self,request, response): :#基于请求响应
print("md1 process_response 方法!", id(request)) #在视图之后
return response
从下图看,正常的情况下按照绿色的路线进行执行,假设中间件1有返回值,则按照红色的路线走,直接执行该类下的 process_response 方法返回,后面的其他中间件就不会执行。
process_view(self, request, view_func, view_args, view_kwargs)
process_view 方法格式如下:
process_view(request, view_func, view_args, view_kwargs)
process_view 方法有四个参数:
request 是 HttpRequest 对象。
view_func 是 Django 即将使用的视图函数。
view_args 是将传递给视图的位置参数的列表。
view_kwargs 是将传递给视图的关键字参数的字典。
view_args 和 view_kwargs 都不包含第一个视图参数(request)。
process_view 方法是在视图函数之前,process_request 方法之后执行的。
返回值可以是 None、view_func(request) 或 HttpResponse 对象。
返回值是 None 的话,按正常流程继续走,交给下一个中间件处理。
返回值是 HttpResponse 对象,
Django 将不执行后续视图函数之前执行的方法以及视图函数,直接以该中间件为起点,倒序执行中间件,且执行的是视图函数之后执行的方法。
返回值是 view_func(request),
Django 将不执行后续视图函数之前执行的方法,提前执行视图函数,然后再倒序执行视图函数之后执行的方法。
当最后一个中间件的 process_request 到达路由关系映射之后,返回到第一个中间件 process_view,然后依次往下,到达视图函数。
实例
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行
def process_response(self,request, response): :#基于请求响应
print("md1 process_response 方法!", id(request)) #在视图之后
return response
def process_view(self,request, view_func, view_args, view_kwargs):
print("md1 process_view 方法!") #在视图之前执行 顺序执行
#return view_func(request)
process_exception
process_exception 方法如下: process_exception(request, exception)
参数说明:
request 是 HttpRequest 对象。
exception 是视图函数异常产生的 Exception 对象。
process_exception 方法只有在视图函数中出现异常了才执行,按照 settings 的注册倒序执行。 在视图函数之后,在 process_response 方法之前执行。
process_exception 方法的返回值可以是一个 None 也可以是一个 HttpResponse 对象。
返回值是 None,页面会报 500 状态码错误,视图函数不会执行。process_exception 方法倒序执行,然后再倒序执行 process_response 方法。
返回值是 HttpResponse 对象,页面不会报错,返回状态码为 200。视图函数不执行,该中间件后续的 process_exception 方法也不执行,直接从最后一个中间件的 process_response 方法倒序开始执行。
若是 process_view 方法返回视图函数,提前执行了视图函数,且视图函数报错,则无论 process_exception 方法的返回值是什么,页面都会报错, 且视图函数和 process_exception 方法都不执行。 直接从最后一个中间件的 process_response 方法开始倒序执行:
实例
class MD1(MiddlewareMixin):
def process_request(self, request):
print("md1 process_request 方法。", id(request)) #在视图之前执行
def process_response(self,request, response): :#基于请求响应
print("md1 process_response 方法!", id(request)) #在视图之后
return response
def process_view(self,request, view_func, view_args, view_kwargs):
print("md1 process_view 方法!") #在视图之前执行 顺序执行
#return view_func(request)
def process_exception(self, request, exception):#引发错误 才会触发这个方法
print("md1 process_exception 方法!")
# return HttpResponse(exception) #返回错误信息
process_template_response(self,request,response)
中间件的执行流程
请求到达中间件之后,先按照正序执行每个注册中间件的process_request方法,
process_request方法返回的值是None,就依次执行,
如果返回的值是HttpResponse对象,不再执行后面的process_request方法,
而是执行当前对应中间件的process_response方法(注意不是掉头执行所有的process_response方法),将HttpResponse对象返回给浏览器。
也就是说:如果MIDDLEWARE中注册了6个中间件,执行过程中,第3个中间件返回了一个HttpResponse对象,那么第4,5,6中间件的process_request和process_response方法都不执行,顺序执行3,2,1中间件的process_response方法。
process_request方法都执行完后,匹配路由,找到要执行的视图函数,先不执行视图函数,先执行中间件中的process_view方法,process_view方法返回None,继续按顺序执行,所有process_view方法执行完后执行视图函数。假如中间件3 的process_view方法返回了HttpResponse对象,则4,5,6的process_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行。
process_template_response和process_exception两个方法的触发是有条件的,执行顺序也是倒序。总结所有的执行流程如下: