Django中间件

Django中间件

HTTP请求周期初识

在HTTP请求周期中,之前的了解是:用户请求->URL->view视图->url->用户

实际在用户请求和URL之间是中间件

Django 的中间件的本质是类,有几个中间件,就有经过几个类,每个类都有相应的方法。

Django中的中间件

Django的中间件在setting中MIDDLEWARE

中间件是有顺序的,按照setting中的从上到下顺序执行

Django1.10以上的版本中,当请求从上到下执行,如到达csrf出现问题,会从同一级别的csrf返回。

在之前的版本中,请求到达csrf出现问题,会从最后一个中间件返回。

自定义中间件

可以在当前的中间件的基础上进行修改,也可以自己定制新的中间件

小功能:

  • 比如,黑名单功能,请求来的时候判断用户的IP是否在黑名单中,如果在,禁止请求

  • 在中间件中添加装饰器判断用户是否登录

自定义中间件:

  • 继承MiddlewareMixin
  • process_request 可以没有返回值,有返回值的时候直接从同级别的位置返回
  • process_response 有三个参数,必须有返回值

中间件

1
2
3
4
5
6
7
8
9
10
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.request")
def process_response(self, request, response): # 还有一个response参数
print("m1.response")
return response

视图

1
2
3
4
5
from django.shortcuts import render,redirect,HttpResponse
def test(rquest):
print('test')
return HttpResponse("ok")

结果:

1
2
3
m1.request
test 视图函数的执行
m1.response

process_request有返回值的情况

1
2
3
4
5
6
7
8
9
10
11
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.request")
return HttpResponse('okokoko') # 这里添加了返回值
def process_response(self, request, response): # 还有一个response参数
print("m1.response")
return response

结果:没有执行视图函数

1
2
m1.request
m1.response 直接从自己的方法返回

注册中间件

按顺序执行

1
2
3
4
5
6
7
8
9
10
11
12
13
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',
# 'md.M1',
# 'md.M2',
'm1.M1', # 自己的中间件 文件名+类名
]

深入HTTP请求周期

首选要明白的是web框架的本质是socket,但是Django是没有的,默认的wsgiref,生产环境用的是uwsgi

WSGI(Web Server Gateway Interface)Web服务网关接口已经成为了一种规范

wsgi是Django开始的地方

自定义中间件view

下面的情况是执行完m1的request后执行m2的request.

执行view的时候重新返回m1的view,然后是m2的view

中间执行view视图函数

最后执行m2的response,m1的response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.process_request")
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m1.process_view")
def process_response(self, request, response):
print("m1.process_response")
return response # response必须要有返回值
class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.process_request')
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m2.process_view")
def process_response(self, request, response):
print('m2.process_response')
return response #

结果:

1
2
3
4
5
6
7
m1.process_request
m2.process_request
m1.process_view
m2.process_view
test
m2.process_response
m1.process_response

*在view中是用callback方法

通过callback找到了视图函数的名字,callback加括号就是执行视图函数一次

注意的是m1的process_view没有返回值的时候是执行一次view中的test函数

有返回值的时候m2的process_view不会执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.process_request")
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m1.process_view")
response = callback(request, *callback_args, **callback_kwargs)
# 这里是找函数 url对应的函数名
# return response 有response的时 从这里返回
def process_response(self, request, response):
print("m1.process_response")
return response # response必须要有返回值
class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.process_request')
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m2.process_view")
def process_response(self, request, response):
print('m2.process_response')
return response #

结果:

1
2
3
4
5
6
7
8
m1.process_request
m2.process_request
m1.process_view
test # 这是callback执行的
m2.process_view
test
m2.process_response
m1.process_response

process的方法

  • process_request
  • process_response 一定要有返回值
  • process_view
  • process_exception(错误异常)
  • process_template
    • 视图函数中有render方法才执行
    • 自己写类进行封装
      返回对象有render方法
1
2
3
4
5
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)

中间件应用

对所有请求或一部分请求做批量处理

例如把所有的请求筛选,缓存中有,直接从缓存中拿

© 2018 Peter's Blog Center All Rights Reserved.
Theme by hiero