中间件
-
中间件的引入
- django中的中间件
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件. - 中间件的结构
# 中间件中可以定义5个方法,分别是:
# 执行视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
process_request(self,request) :
# 调用视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
process_view(self, request, callback, callback_args, callback_kwargs):
# 在视图刚好执行完毕之后被调用,在每个请求上调用,返回实现了render方法的响应对象
process_template_response(self,request,response):
# 当视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象
process_exception(self, request, exception)
# 所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象
process_response(self, request, response)
-
中间的执行顺序
- 函数示例
# 一个中间件就是一个可调用的对象,他会接收一个request并返回一个请求
# 一个中间件可以是一个函数
def simple_middleware(get_response):
# 一次性设置和初始化 启动项目时执行且只执行一次
print('我是项目开启时调用,且只执行一次')
def middleware(request):
# 处理请求之前被执行的代码
# 调用视图,或者执行后面的中间件
print('我是在视图调用前调用-------')
response = get_response(request)
# 处理请求,响应之后的代码
# 视图已经被调用
print('视图已调用-------')
return response
return middleware
- 激活中间键
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',
'index.middleware.simple_middleware'
]
-
展示
- 反爬小案例 -- 只有谷歌浏览器才能访问
-
原理
- 代码
from django.http import HttpResponseForbidden
# 一个中间件就是一个可调用的对象,他会接收一个request并返回一个请求
# 一个中间件可以是一个函数
def simple_middleware(get_response):
# 一次性设置和初始化 启动项目时执行且只执行一次
print('我是项目开启时调用,且只执行一次')
def middleware(request):
# 处理请求之前被执行的代码
# 调用视图,或者执行后面的中间件
print('我是在视图调用前调用-------')
user_agent = request.META['HTTP_USER_AGENT']
if not 'chrome' in user_agent.lower():
# 返回403
return HttpResponseForbidden()
response = get_response(request)
# 处理请求,响应之后的代码
# 视图已经被调用
print('视图已调用-------')
return response
return middleware
- 类方法实现中间件
-
方法一
1.在主目录下创建了一个mymiddleware.py的文件.
2.在.py的文件中创建一个MyException的类
3.自定义时你想要加在哪一块加功能就定义相对于的方法,不用全部都定义.
方法二
1.在mymiddleware.py的文件中创建一个UserMiddleware的类
2.这个例子是给request请求增加一个myuser的属性
3.以这一句为分界,分别在view之前执行和view之后执行
# 还可以写成一个类,并且它的实例可以被调用call
class SimpleMiddleWare:
def __init__(self, get_response):
self.get_response = get_response
# 一次性设置和初始化 启动项目时执行且只执行一次
print('我是项目开启时调用,且只执行一次')
def __call__(self, request):
# 在每一个请求都会调用
# 处理请求之前被执行的代码
# 调用视图,或者执行后面的中间件
print('我是在视图调用前调用-------')
response = get_response(request)
# 处理请求,响应之后的代码
# 视图已经被调用
print('视图已调用-------')
return response
-
注册
上下文处理器(需要在所有的模板上显示特定变量)
- 上下文处理器的引入
上下文处理器就是创建模板变量.
# 在settings.py中,包含了当前使用的上下文处理器。他的作用是可以给每一个模板都提供相同的变量
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
- 自定义上下文处理器例子
在刚才的中间件的例子中,我们给request 增加了一个myuser的属性,而如果每个模板中也就是每个页面上都需要用到登录用户名这个变
量名的话, 那么我们也可以把这个变量在上下文处理器中将变量传给模板.
1.在主目录下创建了一个mycontextprocessor.py的文件.
2.在mycontextprocessor.py的文件中创建一个myuser的函数
3.必须传入request这个参数
4.必须返回一个字典类型的对象.
中间件和上下文的总结:
我们刚才分别用中间件和上下文完成了跟登录用户有关的例子, 最后的结果都是能在页面上显示用户的用户名了.
- 中间件是在用户请求到响应的过程中去加入一些额外的逻辑功能,例子中给request增加了一个myuser的属性.
- 上下文是给所有的模板增加变量,例子中给模板增加了一个myuser的变量.