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请求流程图



相关文章
|
2月前
|
中间件 Python
理解Django中间件及其应用实例
理解Django中间件及其应用实例
34 0
|
4月前
|
监控 安全 中间件
Python Django 后端架构开发: 中间件架构设计
Python Django 后端架构开发: 中间件架构设计
44 1
|
4月前
|
安全 中间件 项目管理
Django 后端架构开发:分页器到中间件开发
Django 后端架构开发:分页器到中间件开发
46 1
|
4月前
|
安全 中间件 开发者
Django中间件
【8月更文挑战第21天】
27 5
|
4月前
|
中间件 数据库连接 UED
Django中间件秘籍:如何用几行代码让你的应用变得超级强大?
【8月更文挑战第31天】中间件是Django框架的核心特性,位于视图与HTTP服务器之间,允许全局处理请求和响应,增强Web应用功能。通过实现`MiddlewareMixin`类的方法,如`process_request`和`process_response`,可以轻松实现请求预处理或响应后处理。中间件应用场景广泛,包括用户认证、CSRF防护和数据库连接管理等。创建并配置中间件需将其加入`settings.py`的`MIDDLEWARE`列表,顺序决定执行优先级。合理利用中间件能提高代码重用性和应用性能,带来更好的用户体验。
55 0
|
4月前
|
前端开发 中间件 索引
Django入门到放弃之中间件
Django入门到放弃之中间件
|
6月前
|
中间件 开发者 C++
Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用
Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用
|
7月前
|
中间件 Python
中间件应用Django Middleware(Python)
【5月更文挑战第3天】中间件应用Django Middleware(Python)
82 6
中间件应用Django Middleware(Python)
|
6月前
|
缓存 监控 中间件
探究Django中间件的神奇:功能、应用场景和核心方法
在Django中,中间件是一个强大的概念,它们提供了一种灵活的方式来处理请求和响应。本文将探讨Django中间件的基本概念、常见应用场景以及中间件类中的父类和核心方法。
|
6月前
|
中间件 开发者 Python
Django——中间件
Django——中间件