python 中间件

中间件
一.什么是中间件
中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django
的输入和输出。每个中间件组件都负责做一些特定的功能,中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的
操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在处理请求的特定的时间去执行这些方法。
二.自定义中间件
(一)中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
process_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)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是
HttpResponse对象,则直接将该对象返回给用户。
(二)自定义一个中间件示例
1.导入 from django.utils.deprecation import MiddlewareMixin
2.在settings.py的MIDDLEWARE配置项中注册上述两个自定义中间件:
'app01.my_middlewares.MD2',
'app01.my_middlewares.MD1'
三.方法:
1.process_request
执行时间:视图函数之前
参数:request (同视图函数参数)
执行顺序:按注册的顺序
返回值:如果是none: 则继续按规则执行
如果是 Httpresponse对象: 跳过后面中间件的request方法,直接执行相对应的中间件的response方法.
示例:
class MD1(MiddlewareMixin):
def process_request(self,request): #正序
print("这是MD1request方法")
2.process_response
执行时间:视图函数后
参数:request response
执行顺序:按倒序执行
返回值:必须return response
如果返回Httpresponse对象,返回当前Httpresponse对象则直接从最后一个中间件的response开始执行
示例
class MD1(MiddlewareMixin):
def process_response(self,request,response): #倒序
print('这是MD1response方法')
return response

3.process_view
执行时间:request之后,视图函数之前
参数:self, request, view_func, view_args, view_kwargs
执行顺序:按注册顺序执行
返回值:如果是none,正常执行
如果是Httpresponse对象,不执行后面的中间件的view方法,,直接从最后一个中间件的response方法开始执行(执行全部)
示例:
class MD1(MiddlewareMixin):
def process_view(self,request,view_func,view_args,view_kwargs): #顺序
# view_func(request)
print('这是MD1view 方法')
# return HttpResponse('ok') #不执行MD2的view方法从最后一个中间件的response开始执行倒序
4.process_exception 报错才会触发
执行时间: 视图函数之后,response之前
参数: self, request, exception
执行顺序:倒序执行
返回值:返回none:不对错误进行处理,交给下一个中间件进行处理
返回Httpresponse对象:不执行后面的中间件的该方法,直接执行所有中间件的response方法
示例:
class MD1(MiddlewareMixin):
def process_exception(self,request,exception): #报错才显示 视图之后 倒序
print('这是MD1exception 方法')
# return HttpResponse('你出错了') 不执行其之后中间件的exception方法 ,直接从最后一个中间件的response方法开始执行
5.process_template_response(用的比较少) 视图函数返回的对象中有render方法才触发该方法
执行时间:视图函数之后,response之前
参数:(self, request, response)
执行顺序:倒序
返回值:必须有return
视图函数执行完之后,立即执行了中间件的process_template_response方法,顺序是倒序,先执行MD1的,在执行MD2的,
接着执行了视图函数返回的HttpResponse对象的render方法,返回了一个新的HttpResponse对象,接着执行中间件的
process_response方法 (倒序)。

作业:

中间件实现登陆验证
中间件(my_middleware.py):
from django.middleware.security import SecurityMiddleware
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse,redirect
class AuthMD(MiddlewareMixin):
white_list=['/home/',"/login/"] #白名单 定义一个字段白名单(静态属性)
black_list=[''] #黑名单 #定义一个黑名单

def process_request(self,request): #所有请求都必须经过process_request
next_url=request.path_info #获取用户发送请求中的路径
print(next_url) #login
if next_url in self.black_list: #判断 用户请求路径是否在黑名单中
return HttpResponse('This is an illegal URL') #如果在则响应''
elif next_url in self.white_list or request.session.get('user'): #如果路径在白名单中则可以执行(匹配url,视图函数)
return
else:
return redirect('/login/?next={}'.format(next_url)) # 如果是其他则跳转到login页面 后面拼接上用户的路径,
#匹配路径与函数
url.py:
    urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # url(r"^work/",views.work),
    url(r"^login/$",views.login),
    url(r'^index/$',views.index),
    url(r'^home/$',views.home),
]

  

views.py:
from django.shortcuts import render,redirect,HttpResponse
        def index(request):  #登陆后才能访问
            return HttpResponse('这是index')

        def home(request):  #随意访问
            return HttpResponse('这是home')

        def login(request):   #随意访问
            if request.method=='POST':
                user=request.POST.get("user")   #获取用户名
                pwd=request.POST.get('pwd')   #获取密码

                if user=="alex" and pwd=='alex':   #如果验证成功
                    request.session['user']=user     #设置session
                    next_url=request.GET.get('next')#获取路径后面拼接的查找内容
                    if next_url:#如果路径存在
                        return redirect(next_url) #跳转到该页面
                    else:  #如果不存在默认跳转到index页面
                        return redirect('/index/')
            return render(request,'login.html')  #如果是get请求返回login页面

 

login.html:
 <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post">
        {% csrf_token %}
        <p>
            <lable for="user">用户名:</lable>
            <input type="text" name="user" id="user">
        </p>
        <p>
            <lable for="pwd">密码:</lable>
            <input type="password" name="pwd" id="pwd">
        </p>
        <input type="submit" value="登陆">
    </form>
    </body>
    </html>
setting.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',
        'app01.my_middlewares.AuthMD',

    ]

  

posted @ 2018-09-18 21:58  吉喆嚞吉  阅读(957)  评论(0编辑  收藏  举报