zoukankan      html  css  js  c++  java
  • 中间件

     中间件是一个用来处理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
  • 相关阅读:
    Android 4.4 通过源码进行 root 操作
    Android4.4 找不到内部存储空间
    极客时间《从零开始学大数据》学习总结
    C 语言实现 unix 时间戳转换成时间字符串
    数据库设计中各种键的含义
    Sqoop 快速入门
    Intelij idea新窗口打开项目设置
    安装配置Apache2.4和php7.0
    如何让 linux unzip 命令 不输出结果
    允许远程用户登录访问mysql的方法
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10696983.html
Copyright © 2011-2022 走看看