需求:
现在我们好许多个页面,但是这些页面都有一点相似之处,那就是需要登录,当一次登录完成之后,其它的程序都不用登录了。
如果只有几个页面我们可以挨个写登录验证,如果再多了一点,我们可以使用装饰器。
但是如果有成百上千个页面,使用前面的两种方法都怎么方便,在这里就要引出中间件。
中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并在全局上改变django的输入输出。
因为改变的是全局,所以需要谨慎使用。
中间件只是实现了某些特定方法的普通对象,所以定义一个中间件很容易,你只需要定义一个普通的python类,
然后实现如下四个方法中的某一个或者某几个函数的执行的时机。
- process_request:接收request之后确认所执行的view之前。
- process_view:确认了所要执行的view知乎view真正执行之前。
- process_response:view执行之后
- process_exception(self,request,exception):view抛出异常
2.添加中间件
通过django-admin生成的项目的setting.py的配置文件中默认有如下设置,
如果你需要添加自己的中间件,你需要在这个地方进行指定。
- MIDDLEWARE_CLASSES = (
- ‘django.middleware.common.CommonMiddleware‘,
- ‘django.contrib.sessions.middleware.SessionMiddleware‘,
- ‘django.middleware.csrf.CsrfViewMiddleware‘,
- ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,
- )
这里指定的顺序和实际运行时运行的顺序相关,
在request阶段:process_request,process_view 按照其所在类在配置中的先后顺序进行,
在response阶段:process_response,process_exception 则按照相反的顺序进行。
还有一点就是在整个流程中,每一个process_response都会执行到,
而其余三种,都可能会因为其他的直接retuen response或者不发生异常而不被执行到。
下面是客户端请求的流程:
现在解决最初的问题:
现在views中有4个视图函数:
def login(request): if request.method == "GET": return render(request,"login.html") if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") if user == "kebi" and pwd == "123": request.session["user_info"] = {"id":"001","name":"kebi"} return redirect("/index/") else: return redirect(‘/login/‘) def index(request): return HttpResponse("首页") def class_list(request): return HttpResponse("班级页") def teacher_list(request): return HttpResponse("老师页")
然后编写中间件,随便添加一个目录和一个文件然后创建一个类:
在settings中添加设置:
最后定义:中间件类
from django.shortcuts import HttpResponse,redirect,render from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self,request): #如果不加下面的这一句话,我们会发现一直在login这里循环 # if request.path_info == "/login/": return None #r如果路径是login就不用跳转 #获取Session信息 user_info = request.session.get("user_info") if not user_info: return redirect("/login/") def process_response(self,request,response): return response
这样就可以满足条件,只要登录一次所有请求免登陆。