django -- 中间件(二)

简介: django -- 中间件

process_exception


process_exception有两个参数,一个上HttpRequest对象,一个exception上视图函数异常产生的Exception对象

这个方法只有在视图函数中出现了异常才执行。它返回的值可以是一个None也可以是一个HttpResponse对象,如果是Response对象,Django将调用模版和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常,如果返回一个None,则交给下一个中间件的process_exception方法来处理异常,它的执行顺序也是按照中间件的注册顺序从下往上执行

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, render, redirect
class Middle1(MiddlewareMixin):
    def process_request(self, request):
        print('这是中间件1中的process_request方法')
    def process_response(self, request, response):
        print('这是中间件1中的process_response方法')
        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        print('这是中间件1中的process_view方法')
    def process_exception(self,request, exception):
        print('这是中间件1中的process_exception方法')
class Middle2(MiddlewareMixin):
    def process_request(self, request):
        print('这是中间件2中的process_request方法')
    def process_response(self, request, response):
        print('这是中间件2中的process_response方法')
        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        print('这是中间件2中的process_view方法')
    def process_exception(self,request, exception):
        print('这是中间件2中的process_exception方法')

视图函数如果正常的话

这是中间件2中的process_request方法
这是中间件1中的process_request方法
这是中间件2中的process_view方法
这是中间件1中的process_view方法
我是test视图。。。
这是中间件1中的process_response方法
这是中间件2中的process_response方法

往视图函数里写点异常在看看结果

def test(request):
    print('我是test视图。。。')
    int('weewe')
    return HttpResponse('ok')

结果:

这是中间件2中的process_request方法
这是中间件1中的process_request方法
这是中间件2中的process_view方法
这是中间件1中的process_view方法
我是test视图。。。
这是中间件1中的process_exception方法
这是中间件2中的process_exception方法
Internal Server Error: /test/
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
    response = get_response(request)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\django-project\orm_project\appTest01\views.py", line 55, in test
    int('weewe')
ValueError: invalid literal for int() with base 10: 'weewe'
这是中间件1中的process_response方法
这是中间件2中的process_response方法
[26/Jul/2019 23:12:45] "GET /test/ HTTP/1.1" 500 69084

执行视图函数,遇到异常之后执行process_exception方法,按注册的顺序从下往上执行,执行完之后在执行process_response(从上往下)

 

那如果有return了呢,因为是从下往上执行的,我们给middle1加上return

结果:

这是中间件2中的process_request方法
这是中间件1中的process_request方法
这是中间件2中的process_view方法
这是中间件1中的process_view方法
我是test视图。。。
这是中间件1中的process_exception方法
这是中间件1中的process_response方法
这是中间件2中的process_response方法

当遇到process_exception里的return时,注册顺序之前的中间件的process_exception方法不走了。执行所有中间件的process_response方法

总结:

1.process_exception的执行条件是有异常时才会执行,在视图函数之后,在process_response之前

2.参数exception错误对象信息

3.返回值:None,正常走。HttpResponse对象,注册顺序之前的中间件的process_exception方法不走了。执行所有中间件的process_response方法,把process_exception里的返回值显示在浏览器上

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


process_template_response


process_template_response(self, request, response)

它的参数,一个HttpRequest对象,response是TemplateResponse对象(由视图函数或者中间件产生)。

process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, render, redirect
class Middle1(MiddlewareMixin):
    def process_request(self, request):
        print('这是中间件1中的process_request方法')
    def process_response(self, request, response):
        print('这是中间件1中的process_response方法')
        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        print('这是中间件1中的process_view方法')
    def process_exception(self,request, exception):
        print('这是中间件1中的process_exception方法')
    def process_template_response(self, request, response):
        print("这是中间件1中的process_template_response方法")
        return response
class Middle2(MiddlewareMixin):
    def process_request(self, request):
        print('这是中间件2中的process_request方法')
    def process_response(self, request, response):
        print('这是中间件2中的process_response方法')
        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        print('这是中间件2中的process_view方法')
    def process_exception(self,request, exception):
        print('这是中间件2中的process_exception方法')
        return HttpResponse(str(exception))
    def process_template_response(self, request, response):
        print("这是中间件2中的process_template_response方法")
        return response

视图函数

def test(request):
    print('我是test视图。。。')
    def render():
        print("我是render")
        return HttpResponse("render。。。")
    res = HttpResponse("OK")
    res.render = render
    return res

结果:

这是中间件2中的process_request方法
这是中间件1中的process_request方法
这是中间件2中的process_view方法
这是中间件1中的process_view方法
我是test视图。。。
这是中间件1中的process_template_response方法
这是中间件2中的process_template_response方法
我是render
这是中间件1中的process_response方法
这是中间件2中的process_response方法

视图函数执行完之后,立即执行了中间件的process_template_response方法,顺序是倒序,先执行middle1的,在执行middle2的,接着执行了视图函数返回的HttpResponse对象的render方法,返回了一个新的HttpResponse对象,接着执行中间件的process_response方法。


中间件的执行流程


我们了解了中间件的五个方法,以及什么时候执行,参数,返回值

请求在到达中间件之后,先按照正序执行每个中间件中的process_request方法,如果process_request返回的是None,就依次执行。如果返回的是HttpResponse对象,不在执行后面的 process_request方法,而是执行当前中间件对应的process_response方法,将HttpResponse对象返回给浏览器。也就是说,如果MIDDLEWARE中注册了6个中间件,执行过程中,第3个中间件返回了一个HttpResponse对象,那么第4,5,6中间件的process_request和process_response方法都不执行,顺序执行3,2,1中间件的process_response方法。

process_request方法都执行完后,匹配路由,找到要执行的视图函数,找到之后先不执行视图函数,先执行中间件中的process_view方法,process_view方法如果返回None,继续按顺序执行,所有process_view方法执行完 后执行视图函数。假如中间件中的第三个process_view方法返回了一个httpResponse对象,则4,5,6的processs_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行

process_template_response和process_exception两个方法的触发是有条件的,执行顺序也是倒序,总结所有的执行流程如下


Django请求流程图



相关文章
|
5月前
|
中间件 程序员 开发工具
Django实践-08中间件的应用
Django实践-08中间件的应用
Django实践-08中间件的应用
|
6天前
|
存储 监控 中间件
使用Django的中间件可以解决哪些问题
【4月更文挑战第25天】Django中间件用于处理用户认证、CSRF防御、点击劫持防护、请求响应修改、自定义需求、全局处理、异常处理、数据压缩、Session管理、URL重写、限流和CORS支持。它们按顺序执行,提供安全性、灵活性及定制功能,优化Web开发体验。
7 0
|
16天前
|
中间件 API 文件存储
Django的扩展包与中间件:增强应用功能的利器
【4月更文挑战第15天】本文介绍了Django的扩展包和中间件,两者用于增强Django应用功能。扩展包是可重用的应用,提供额外功能,如用户认证和API开发。选择合适的扩展包,通过安装、配置,可轻松集成到项目中。中间件则在请求和响应之间执行操作,如身份验证和权限控制。创建中间件类并添加到settings.py中,实现特定功能。扩展包和中间件常结合使用,以实现更复杂的应用需求,提高开发效率和应用性能。
|
9月前
|
前端开发 中间件 数据安全/隐私保护
【Django】创建用户,中间件,表单组件
【Django】创建用户,中间件,表单组件
48 0
|
9月前
|
XML 中间件 数据格式
Django 高级指南:深入理解和使用类视图和中间件
Django 是一款强大的 Python Web 框架,它提供了一套完整的解决方案,让我们能够用 Python 语言快速开发和部署复杂的 Web 应用。在本文中,我们将会深入研究 Django 中的两个高级特性:类视图(Class-Based Views)和中间件(Middleware)。
|
5月前
|
缓存 中间件 Python
Python Web 开发: 解释 Django 中的中间件是什么,以及如何使用?
Python Web 开发: 解释 Django 中的中间件是什么,以及如何使用?
|
6月前
|
中间件 Python
25 Django高级- 中间件
25 Django高级- 中间件
27 0
|
9月前
|
中间件 Python
|
9月前
|
中间件 开发者 Python
[Python]Django中间件
[Python]Django中间件
|
10月前
|
中间件 开发者 Python
16-Django-基础篇-中间件
16-Django-基础篇-中间件