中间件

 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量,低级的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件都负责做一些特点的功能.

中间件本质上就是一个类,类中定义了几个方法,Django框架会在处理请求的特定的时间去执行这些方法

settings文件中的MIDDLEWARE配置就是用来存放中间件的

自定义中间件

 中间件可以定义五个方法:

  • 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)

 一般在app文件夹下创建文件夹,在文件夹中的py文件中进行定义

 process_request(self,request)

执行时间: 请求到来后,路由匹配之前

执行顺序: 按照注册顺序执行

参数: request --- 项目中所有的request都是同一个

返回值: 

  None: 正常流程

  HttpResponse对象: 直接执行当前中间件的process_response方法,后面中间件中的process_request方法,视图函数都不执行

process_response(self,request,response)

执行时间: 视图函数执行之后

执行顺序: 按照注册顺序倒序执行

参数: 

  request --- 项目中所有的request都是同一个

  response - 返回的响应对象

返回值: HttpResponse    必须返回

process_view(self,request,view_func,view_args,view_kwargs)

执行时间: 路由匹配之后,函数执行之前

执行顺序: 按照注册的顺序执行

参数:

  request --- 项目中所有的request都是同一个

  view_func --- 视图函数

  view_args --- 传给视图的位置参数

  view_kwargs --- 传给视图的关键字参数

返回值:  

  None: 正常流程

  HttpReaponse对象: 直接执行最后一个中间件的process_response方法,倒序执行,返回给浏览器,后面中间件的process_view方法,视图都不执行

process_exception(self,request,exception)

执行时间: 视图函数有异常时才执行

执行顺序: 按照注册顺序 倒序执行

参数: 

  request --- 项目中所有的request都是同一个

  exception --- 错误的对象

返回值:

  None: 正常流程,交给下一个中间件处理异常,如果每个中间件都返回None,会自动交给django来处理异常(大黄页)

  HttpResponse: 直接执行最后一个中间件的process_response方法,倒序执行,返回给浏览器

process_template_response(self,request,response)

执行时间: 视图函数执行之后  要求视图函数返回的对象是TemplateResponse对象  或者是有render方法的HttpResponse对象

执行顺序: 按照注册顺序 倒序执行

参数: 

  request --- 项目中所有的request都是同一个

  response --- 视图函数返回的响应对象

返回值: HttpResponse对象  必须返回

请求流程(生命周期)

 

 登录校验

# url设置
from app01 import views

urlpatterns = [
    url(r'^login/', views.login),
    url(r'^index/', views.index),
    url(r'^home/', views.home),
]

# views文件
from django.shortcuts import render, HttpResponse,redirect


def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'alex' and pwd == '123':
            # 设置session
            request.session['user'] = user
            return_url = request.GET.get('return_url')
            if return_url:
                return redirect(return_url)
            else:
                return redirect('/index/')
        else:
            return render(request, 'login.html',{'err_msg':'用户名或密码错误'})

    return render(request, 'login.html')


def index(request):
    return HttpResponse('<h1>index</h1>')


def home(request):
    return HttpResponse('<h1>home</h1>')

# login.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
     {% csrf_token %}
    <div>
    用户名 <input type="text" name="user">
</div>
<div>
    密码 <input type="password" name="pwd">
</div>
    <div>{{ err_msg }}</div>
<button>登录</button>
</form>

</body>
</html>


# middleware文件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse,render


class AuthMD(MiddlewareMixin):
    white_list = ['/index/','/login/']
    def process_request(self,request):
        return_url = request.path_info
        # 如果是在白名单内或者登录过的用户,走正常流程,返回None
        if return_url in self.white_list or request.session.get('user'):
            return
        # 否则返回登录页面,将当前页面作为参数写在url里
        else:
            return redirect('/login/?return_url={}'.format(return_url))
示例

登录限制(5秒内最多访问3次)

import time
visit_history = {}
class AuthMD2(MiddlewareMixin):
    def process_request(self, request):
        # 获取访问ip
        ip = request.META.get('REMOTE_ADDR')
        # 获取当前时间
        now = time.time()
        # 获取当前ip之前的访问时间,没有就设置一下
        history = visit_history.get(ip,[])
        new_list = []   # 存储5秒内的访问时间
        for i in history:
            if now - i < 5:
                new_list.append(i)

        if len(new_list) >= 3:
            return HttpResponse('访问太频繁,请稍后重试')

        new_list.append(now)
        visit_history[ip] = new_list
View Code

 

posted @ 2019-04-12 16:43  Sandy-123  阅读(135)  评论(0编辑  收藏  举报