Django学习之七:Django 中间件

目录

  • Django 中间件

    • 自定义中间件 - - - 大体两种方式
    • 将中间件移除
    • 实例
    • 总结

Django 中间件

Django中间件可看作是包裹在django处理机制的外层,Httprequest和Httpresponse都要经中间件处理,从而起到全局钩子的作用,可以达到一些目的:如过滤请求,预处理请求,响应修改等。

我理解,很多基于会话的应用系统,都可以设计中间件环节。如数据库系统。中间件可以起到全局钩子的作用。django的中间件的设计就是一种递归顺序调用,利用httprequest作为递归调用的参数,httpresponse作为递归调用的return返回。

Django提供了内置的一些中间件。思考:request对象中的user属性中的用户对象是怎么来的,就是会话中间件和认证中间件处理session_id,获取用户对象,从而将用户对象放入request对象中,再交与view中进行处理。request对象在中间件开发中起到了载体的作用,非常重要。

中间件框架,设计上就是嵌套调用,初始化一个中间件函数或者中间件对象;中间件函数的初始化通过一个外层的中间件工厂函数;中间件对象的初始化当然是**中间件类的__init__()函数**喽。这两种的初始化,工厂函数和类__init__()都需要传入一个get_response函数,这个get_response的传入是django引擎会带入的,一般是初始化后的中间件列表的下一个中间件函数,或者对象,相当于就是嵌套调用递归下去,当最后的view函数处理完后再一层一层返回response,再进行response返回的中间件过程处理。原理设计就是嵌套递归返回模型(我自己起的名字,知道想表达的意思就好):

自定义中间件 - - - 大体两种方式

中间件工厂函数方式

重点

def simple_middleware(get_response):
    # One-time configuration and initialization.

    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        # 注意这里的代码是view之前还是之后,两种情景的分隔就是下面这个函数调用,这是基于递归调用设计的关键之处。

        response = get_response(request)

        # 下面的就是view处理过后,可以处理httpresponse对象。
        # Code to be executed for each request/response after
        # the view is called.

        return response

    return middleware  # 这是django初始化时调用中间件工厂函数,返回中间件函数。

基于中间件类方式

要点

  • 导入父类from django.utils.deprecation import MiddlewareMixin
  • 自定义自己的中间件类继承上条导入的父类
  • 定义要中间件处理的django生命周期的环节处理函数:
    • process_request(self,request)
    • process_view(self, request, callback_view, callback_args, callback_kwargss)
    • process_template_response(request, response)
    • process_response(self, request, response)
    • process_exception(self, request, response, except)
  • 激活中间件,在settings中的MIDDLEWARE列表中放置中间件类或者中间件工厂函数。注意放置在列表中的位置,这个很重要,因为中间可能存在依赖关系(request和response就像就中间件之间传递个的信息的载体;如auth中间件就要放在session中间件后面)。列表中就中间件的full python path(python全路径)字符串.
  • 至于中间件程序模块文件,可以放在python path的任何地方,建议和组件相关放一起。
# 基于类的方式一
from django.utils.deprecation import MiddlewareMixin

class MyMiddle01(MiddlewareMixin):
    # 1. 定义中间件功能,具体处理整个django请求和响应的生命周期的哪一环节。
    # 2. 主要有request请求到达环节;路由Urlconf后View处理前的view预处理环节;View处理过程中抛出异常的对该异常响应的处理环节(异常情况);正常情况下view返回的response环节;还有一个模版环节(不常用);
    def process_request(self, request):
        pass

    def process_view(self, request, callback_view, callback_args, callback_kwargs):
        callback_view(request, *callback_args, *callback_kwargs)
        pass

    def process_template_response(request, response):
        pass

    def process_response(self, request, response):
        return response

    def process_exception(request, except):
        pass

# 基于类的方式二

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    def process_view():
        pass

    def process_exception():
        pass

    def process_template_response():
        pass    

将中间件移除

  1. 方式一:将中间件从配置中移除。
  2. 方式二:中间件初始化是抛出MiddlewareNotUsed异常即可,在初始化中间件函数或者对象时。

实例

权限鉴别中间件

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse
import re

class RbacPermissionMiddleware(MiddlewareMixin):
    """
    请求访问权限中间件
    """

    def process_request(self, request):
        """
        权限check
        :param request:
        :return:
        """
        req_path = request.path_info
        print(‘用户请求uri‘, req_path)
        # 定义白名单url
        white_list = [‘/login/‘, ‘/register/‘]
        for url in white_list:
            url = ‘^%s$‘ % url
            if re.match(url, req_path):
                return None  # 如果请求权限是白名单中,那么中间件返回一个None,就会进行下一个中间件处理流。

        # 从session中获取权限url列表
        p_list = request.session.get(‘permissions‘)
        if not p_list:
            return HttpResponse(‘未获取用户权限信息,请登录!‘)

        p_flag = False
        for p_url in p_list:
            p_url = ‘^%s$‘ % p_url
            if re.match(p_url, req_path):
                p_flag = True
                break
        if not p_flag:
            return HttpResponse(‘没有访问权限!‘)

总结

  1. 中间件函数就类似一个view函数,参数获取request,return返回response。只不过需要递归调用下一个中间件函数。(下一个中间件函数,是中间件工厂函数通过闭包传递给中间件函数的)
  2. 自定义中间件有多种形式:工厂函数,中间件类。
  3. 中间件注册到django项目时,有顺序性。
  4. 中间件会影响全局性能,毕竟所有请求都会进出都需要通过中间件。
  5. 额外的request_process()等都是只能创建在基于类的中间件,因为这些都是通过类的反射方式调用的。 或者异常触发,或者urlconf触发。。。

  6. 中间件函数还提供内部额外的改变请求和响应的路由路径。如:

    视图函数正常执行时:

视图函数抛出异常时:

原文地址:https://www.cnblogs.com/ZJiQi/p/9589177.html

时间: 2024-08-08 04:17:42

Django学习之七:Django 中间件的相关文章

Django学习之django自带的contentType表

Django学习之django自带的contentType表 通过django的contentType表来搞定一个表里面有多个外键的简单处理: 摘自:https://blog.csdn.net/aaronthon/article/details/81714496 contenttypes 是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中. models.py文件的表结构写好后,通过makemigrations和migrate两条命令

Django学习系列之中间件

中间件的定义 中间件是一个.一个的管道,如果相对任何所有的通过Django的请求进行管理都需要自定义中间件 中间件可以对进来的请求和出去的请求进行控制 中间件是一类 django请求生命周期 自定义中间件 process_request(self,request): 请求到达之后之后先执行这个中间件 process_view(self, request, callback, callback_args, callback_kwargs): process_exception(self, requ

django 学习-15 Django会话Cookie

1.django.admin.py  startproject   cs3 cd cs3 django.admin.py   startapp   blog 2.    vim urls.py url(r'^regist/$','blog.views.regist'),       注册    url(r'^login/$','blog.views.login'), 登录    url(r'^index/$','blog.views.index'),      跳转界面    url(r'^lo

django 学习-11 Django模型数据模板呈现

1.for author in Author.objects.all(): for book in author.book_set.all(): print   book 2.vim blog/views.py from blog.models  import Author,Book from  django.shortcuts   import  render_to_response def show_author(req): authors = Author.objects.all() re

[django学习0-1] django + eclipse基本环境

1.安装django 如果还没有安装python需要先安装python,django1.6对2.6,2.7,3.2或3.3都支持了,这里用的是python2.7.8 然后安装django,发布版本已更新至1.6.6,下载在https://www.djangoproject.com/ (如果已安装旧版需要先删掉旧版) 安装方法win下,先解压django包,然后运行python setup.py install 等待安装完就可以了(需要先设置python环境变量,setup.py在django解压

django 学习-14 Django文件上传 (Admin后台)

1.这种上传方式是用admin后台完成的,用数据库和model做 vim settings.py MEDIA_ROOT = '/headImg/'                                   文件保存在路径(还有后续) #   'django.middleware.csrf.CsrfViewMiddleware',            禁掉这个,跨站不会出问题 'django.contrib.admin',                                

Django 学习之Django Rest Framework(DRF)

一. WEB应用模式 在开发Web应用中,有两种应用模式 1. 前后端不分离 2. 前后端分离 二. API接口 为了在团队内部形成共识.防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本. 目前市面上大部分公司开发人员使用的接口服务架构主要有:restful.rpc. 1. rpc rpc: 翻译成中文:远程过程调用[远程服务调用]. http://www.example.com/api post请求

Django学习之Django shell

Django shell交互式,方便调试,开发. python manage.py shell from blog.models import Article a=Article() a.title='title' a.brief_content='brief_content' a.content='content' a.save() print (a) articles=Article.objects.all() article=articles[0] print(article.title)

Django学习之Django admin

1.后台管理工具 2.读取定义的模型数据 3.Django shell 新增文章复杂,在后台简单方便(编辑,开发,删除) 4.认证用户,显示管理模型,检验输入等功能 5.使用: 第一步 创建管理员用户 python manage.py createsuperuser 启动服务: python manage.py runserver 第二步 页面登陆,管理模型数据: 第三步:注册模型到admin里面 刷新页面: 可知三篇文章都是Article object不好区分,所以开发区分: 至此,admin