django-中间件

一、什么是中间件

官方的说法:

中间件是一个介入Django的请求和响应的处理过程中的钩子框架。它是一个轻量级,底层的“插件”系统,用于在全局修改Django的输入或输出。

通俗理解:
django 中的中间件(middleware),在django中,中间件其实就是一个,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件。

二、激活中间件

要激活一个中间件组件,需要把它添加到你Django配置文件中的MIDDLEWARE_CLASSES 列表中。
在django生成项目之后,在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',
]

默认激活的中间件往往不是必须的,但是有的中间件是相互依赖的,所以,一旦项目生成之后,默认激活的中间件最好不要更改。

三、钩子和应用顺序

在一个中间件中最多可以定义几个函数,答案是5个,因为中间件本质上是一个类,因此可以说一个中间件中最多可以定义5个方法。分别是

- process_request  
- process_view 
- process_response
- process_exception
- process_render_template

上面说中间件像是一个钩子框架,那么这些钩子的处理顺序是怎么样呢?
在请求阶段中,调用视图之前,Django会按照MIDDLEWARE_CLASSES中定义的顺序自顶向下应用中间件。会用到两个钩子:

- process_request()
- process_view()

在响应阶段中,调用视图之后,中间件会按照相反的顺序应用,自底向上。会用到三个钩子:

- process_exception() (仅当视图抛出异常的时候)
- process_template_response() (仅用于模板响应)
- process_response()

像这样

大致流程:
1 request请求先逐个经过中间件的process_request()方法到达路由系统
2 到达路由系统之后在返回第一个中间件,在逐个进入中间件的process_view()进入视图函数
3 进入视图函数之后返回,再经过最后一个中间件到第一个中间件的process_response()方法。
这是正常的流程,但是如果出现异常呢?

  • 当在视图函数中出现异常之后,再经过最后一个中间件到第一个中间件的process_exception()方法
  • 如果返回的有render方法,则调用process_template_response(),经过最后一个中间件到第一个中间件

四、中间件做什么

  • 权限
  • 用户登录验证
  • django的csrf原理
    拓展
    1 csrf防范怎么实现:中间件'django.middleware.csrf.CsrfViewMiddleware', it works!
    2 这个中间件实在什么时候起作用,或者说是内部的哪个钩子起作用,process_view()
    原因也很简单,虽然process_request()的作用时间更早,但是如果想判断一个试图函数是否需要做csrf认证,就需要检查这个视图是否别装饰

1、在FBV中

情况一、

from django.views.decorators.csrf import csrf_protect  # 去掉中间件,当前视图需要认证

@csrf_protect
def users(request):
    pass

情况二、

from django.views.decorators.csrf import csrf_exempt  # 保留中间件,当前视图无需认证 

@csrf_exempt 
def users(request):
    pass

2、在CBV中

在CBV中直接装饰get, post等方法无效的

方式一:

from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.utils.decorators import method_decorator
class StudentsView(View):
	
	@method_decorator(csrf_exempt)
	def dispatch(self, request, *args, **kwargs):
		return super(StudentsView,self).dispatch(request, *args, **kwargs)

	def get(self,request,*args,**kwargs):
		print('get方法')
		return HttpResponse('GET')

	def post(self, request, *args, **kwargs):
		return HttpResponse('POST')

	def put(self, request, *args, **kwargs):
		return HttpResponse('PUT')

	def delete(self, request, *args, **kwargs):
		return HttpResponse('DELETE')

在CBV模式中,请求都要经过View中的dispatch反射执行,所以这里继承父类中dispatch方法增加装饰

方式二:

from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt,name='dispatch')
class StudentsView(View):

	def get(self,request,*args,**kwargs):
		print('get方法')
		return HttpResponse('GET')

	def post(self, request, *args, **kwargs):
		return HttpResponse('POST')

	def put(self, request, *args, **kwargs):
		return HttpResponse('PUT')

	def delete(self, request, *args, **kwargs):
		return HttpResponse('DELETE')
				    

五、自定义中间件

也可以编写自己的中间件。每个中间件组件是一个单独的Python的class,可以定一个或多个上面的方法。
注意事项

  • 中间件的类不能是任何类的子类。
  • 中间件可以存在与你Python路径中的任何位置。 Django所关心的只是被包含在MIDDLEWARE_CLASSES中的配置。通常放在项目目录下

1、中间件存放位置

例如 # 存放中间件的文件夹与manage.py 在同一父目录下

djangoproject
    - middle
        - customize_middleware.py  # 自定义中间件
    - manage.py

2、中间件内部

class RequestExeute(object):
     
    def process_request(self,request):
        pass
    def process_view(self, request, callback, callback_args, callback_kwargs):
        pass
    def process_exception(self, request, exception):
        pass
    def process_response(self, request, response):
        pass

3、激活中间件

在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',
    'middle.customize_middleware.RequestExeute',  # 自定义中间件
]
原文地址:https://www.cnblogs.com/welan/p/9647592.html