中间件的认识
一、django的请求过程
1、图解

2、文字解说
- 1.用户在客户端(浏览器)请求,
http解析域名到wsgi服务器(就是socket端)将用户数据进行初步封装,然后交给web服务器(django、flask)类的框架 - 2.首先进入中间件中,中间件主要作用是对
wsgi封装的数据进行校验及添加其它的信息 - 3.通过中间件后就会路由匹配,查找到对应的视图类或者视图函数
- 4.视图函数或者类会根据内在逻辑使用
model进行页面渲染 - 5.视图类渲染完成后,返回给中间件,中间件可能进一步添加点内容返回给客户端
- 6.最后通过
wsgi封装能被浏览器识别的内容返回给客户端
- 1.用户在客户端(浏览器)请求,
二、关于中间件的理解
- 1、关于中间件的认识官网
- 2、从官网的介绍中间件是:中间件是Django请求/响应处理的钩子框架。它是一个轻巧的低级"插件"系统,用于全局改变
Django的输入或输出。这里说的输入是指request,输出是指response。
三、django中中间件的介绍
- 1、只有放在
settings.py中MIDDLEWARE_CLASSES里面的中间件才算是激活了,才有效果 2、创建项目自带的中间件
MIDDLEWARE_CLASSES = ( 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', )3、中间件排序是有要求的,执行顺序是从上到下的参考文档
四、温习python的反射导包机制
1、
demo的目录结构test foo __init__.py foo.py __init__.py test.py2、
foo.py的代码name = '张三' def foo(): return 'foo函数'3、
test.py的代码import importlib # 利用反射查找到文件,实现导包 foo = importlib.import_module('foo.foo') print(foo.name) # 函数的调用 print(foo.foo())4、
django的中间件就是利用反射的机制实现导包的,手动导包如下:from django.middleware.clickjacking import XFrameOptionsMiddleware
五、自定义中间件
1、中间件要继承一个类
MiddlewareMixinfrom django.utils.deprecation import MiddlewareMixin2、中间件要实现的方法有:主要是
process_request和process_responseprocess_request(self,request)process_view(self, request, view_func, view_args, view_kwargs)process_template_response(self,request,response)process_exception(self, request, exception)process_response(self, request, response)
3、自定义中间件的示例
from django.utils.deprecation import MiddlewareMixin class Md1(MiddlewareMixin): def process_request(self, request): print('md1的request方法') def process_response(self, request, response): print('md1的response方法') return response4、在
settings.py中配置MIDDLEWARE = [ ... 'middle.md1.Md1', ]
六、关于中间件中几个函数的认识
1、
process_request(self,request)客户端请求进入django服务器的过程- 1.参数
request和视图函数或者视图类中的request一样的,可以获得到session的参数的 - 2.当返回值为
None(不写返回值python中默认返回None)的时候会按照顺序执行下一个中间件中的process_request函数,以此类推 - 3.当返回
HttpResponse对象的时候,就不继续执行到视图类中,直接返回HttpResponse来渲染页面 - 4.中间件的
process_request方法是在执行视图函数之前执行的 - 5.当配置多个中间件时,会按照
MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的 - 6.不同中间件之间传递的
request都是同一个对象
- 1.参数
2、
process_response(self, request, response)响应返回给客户端- 1.
request参数和上面process_request中的一样 - 2.
response是视图函数返回的HttpResponse对象。该方法的返回值也必须是HttpResponse对象 - 3.如果自己定义返回
HttpResponse对象的时候就会取代视图中返回的response - 4.
process_response函数是在视图函数或者视图类之后执行的 - 5.如果多个中间件的时候执行顺序也是根据先注册的先执行
- 1.
3、
process_view(self, request, view_func, view_args, view_kwargs)- 1.
Django会在调用视图函数之前调用process_view方法,但是是在process_request之后调用 - 2.
request参数和上面介绍的一样 - 3.
view_func是Django即将使用的视图函数(它是实际的函数对象,而不是函数的名称作为字符串) - 4.
view_args是将传递给视图的位置参数的列表 - 5.
view_kwargs是将传递给视图的关键字参数的字典。 - 6.
view_args和view_kwargs都不包含第一个视图参数(request) - 7.如果返回
None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图 - 8.如果返回一个
HttpResponse对象,Django不会调用适当的视图函数。它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。
- 1.
4、
process_exception(self, request, exception)当视图函数或者类发生异常的时候才会触发- 1.
request是HttpRequest对象 - 2.
exception是视图函数异常产生的Exception对象 - 3.触发条件这个方法只有在视图类中发生异常的时候才会触发执行
- 4.如果返回
None,则交给下一个中间件的process_exception方法来处理异常 - 5.如果返回
HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常 - 6.如果视图函数中无异常,
process_exception方法不执行
- 1.
5、
process_template_response(self, request, response)- 1.
request是一个HttpRequest对象 - 2.
response是TemplateResponse对象(由视图函数或者中间件产生) - 3.
process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)
- 1.
七、使用中间件做登陆拦截的案例
1、视图类
from django.shortcuts import render, redirect # Create your views here. from django.views import View from .models import UserModel class LoginView(View): """ 用户登陆视图类 """ def get(self, request, *args, **kwargs): return render(request, 'login.html') def post(self, request, *args, **kwargs): username = request.POST.get('username', None) password = request.POST.get('password', None) if username and password: user = UserModel.objects.filter(username=username, password=password).first() if user: request.session['user'] = user # 获取登陆前的url next_url = request.GET.get('next', None) if next_url: return redirect(next_url) else: return redirect('index') else: return redirect('/login/') else: return redirect('/login/') class IndexView(View): """ 主页 """ def get(self, request, *args, **kwargs): return render(request, 'index.html', locals())2、中间件
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import redirect class AuthMD(MiddlewareMixin): def process_request(self, request): user = request.session.get('user') if user: pass else: return redirect('/login/')