• 中间件


     中间件是一个用来处理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
  • 相关阅读:
    Qt出现警告 Unescaped backslashes are deprecated!解决办法
    如何在Android应用程序中使用传感器模拟器SensorSimulator
    如何在Android模拟器上安装apk文件
    Qt学习记录--Qt::CaseSensitive
    VS2010/MFC编程入门教程之目录和总结
    TortoiseSVN客户端重新设置用户名和密码
    SVN服务器搭建和使用(三)
    SVN服务器搭建和使用(二)
    SVN服务器搭建和使用(一)
    Eclipse中安装使用SVN
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10696983.html
Copyright © 2020-2023  润新知