内容回顾:

  内容回顾:https://www.cnblogs.com/liwenzhou/p/8343243.html
    1. Cookie和Session
        1. Cookie是什么?
            保存在浏览器端的键值对
        2. 为什么要有Cookie?
            Http请求是无状态,服务端在返回响应的时候让浏览器记录的键值对
        3. Django中如何使用Cookie
            1. 设置Cookie
                rep = redirect('/home/')
                rep.set_cookie(key, value, max_age=60*60*24*7)          --> 设置明文Cookie,有效期是7天
                
                rep.set_signed_cookie(key, value, salt="", max_age=10)  --> 设置加盐的Cookie,有效期是10秒
            2. 获取Cookie
                request.COOKIES    --> 获取请求中的Cookie数据,数据格式是大字典
                    request.COOKIES[key]                不推荐这种写法
                    request.COOKIES.get(key, "默认值")  推荐使用这种方法取值
                request.GET        --> 获取URL里面的参数
                request.POST       --> 获取POST请求的参数
                request.FILES      --> 上传文件的数据
                
                request.get_signed_cookie(key, default="默认值", salt="")   --> 获取加盐的Cookie
                
            3. 删除Cookie(用于注销)
                rep = redirect('/home/')
                rep.delete_cookie("key")
                
    2. Session
        1. Session是什么?
            保存在服务器端的键值对,依赖于Cookie
            
        2. 为什么要有Session?
            Cookie将数据保存在客户端(浏览器)上,数据不安全。
            Cookie存储的数据有限制
            
        3. Django中Session操作
            1. 设置Session
                1. request.session[key] = value
                2. request.session.setdefault(key, value)   --> 有就啥都不干,没有就赋值
            2. 获取Session
                1. request.session[key]
                2. request.session.get(key)  推荐
            3. 删除Session
                1. request.session.delete()
                2. request.session.flush()     --> 删除Cookie和Session
            4. 清空已经过期的session数据
                request.session.clear_expired()
            5. 设置Session过期时间
                request.session.set_expiry(过期时间)
                
        4. Django中Session的配置项
            1. 配置写在settings.py中
            2. 几个常用的配置项
                1. 全局设置Session的过期时间
                    SESSION_COOKIE_AGE = 1209600        --> 默认两周
                2. 设置每次请求来都刷新过期时间
                    SESSION_SAVE_EVERY_REQUEST = True

今日内容:

什么是中间价?

    是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到的MIDDLEWARE配置项。

MIDDLEWARE配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。

我们之前已经接触过一个csrf相关的中间件了?我们一开始让大家把他注释掉,再提交post请求的时候,就不会被forbidden了,后来学会使用csrf_token之后就不再注释这个中间件了。

自定义中间件:

中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

  • 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)

以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

我们现在项目目录下创建一个文件夹来放我们的中间件文件,然后创建yigepy文件。自定义一个中间件。每个中间件都是一个类。

首先我们来学习第一种方法:

process_request:

process_request有一个参数,就是request,这个request和视图函数中的request是一样的。

它的返回值可以是None也可以是HttpResponse对象。返回值是None的话,按正常流程继续走,交给下一个中间件处理,如果是HttpResponse对象,Django将不执行视图函数,而将相应对象返回给浏览器。

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self,request):        print(id(request))   #这个request和视图函数中的request是一样的。打印id可以验证        request.s12 = ’哈哈哈‘  #也可以给request对象设置属性,这个属性可以在视图函数调用。print(‘这是自定义中间件MD1中的 process_request’)        return HttpResponse("呵呵") # 如果有return,则Django将不执行视图函数,而将相应对象返回给浏览器。

class MD2(MiddlewareMixin):#定义多个中间件,    def process_request(self, request):       print("这是自定义中间件MD2中的 process_request")

在settings.py的MIDDLEWARE配置项中注册上述两个自定义中间件:

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware','middlewares.MD1',  # 自定义中间件MD1'middlewares.MD2'  # 自定义中间件MD2  文件名.类名
]

此时,我们访问一个视图,会发现终端中打印如下内容:

这是自定义中间件MD1中的 process_request
这是自定义中间件MD2中的 process_request
这是视图函数。。。。

把MD1和MD2的位置调换一下,再访问一个视图,会发现终端中打印的内容如下:

这是自定义中间件MD2中的 process_request
这是自定义中间件MD1中的 process_request
这是视图函数。。。。。

由此总结一下:

  1. 中间件的process_request方法是在执行视图函数之前执行的。
  2. 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
  3. 不同中间件之间传递的request都是同一个对象

process_response:

它有两个参数,一个是request,一个是response,request就是上述例子中一样的对象,response是视图函数返回的HttpResponse对象。该方法的返回值也必须是HttpResponse对象。

给上述的MD1和MD2加上process_response方法:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponseclass MD1(MiddlewareMixin):  
  def process_request(self,request):    print(id(request))   #这个request和视图函数中的request是一样的。打印id可以验证    request.s12 = ’哈哈哈‘  #也可以给request对象设置属性,这个属性可以在视图函数调用。print(‘这是自定义中间件MD1中的 process_request’)    return HttpResponse(‘阿瑟东’)  def process_response(self,reuqest,response)    print (‘这是自定义中间件MD1中的 process_response’)    return response

class MD2(MiddlewareMixin):#定义多个中间件,    def process_request(self, request):       print("这是自定义中间件MD2中的 process_request")    def process_response(self,reuqest,response)      print (‘这是自定义中间件MD2中的 process_response’)      return response

访问一个视图,看一下终端的输出:

这是自定义中间件MD1中的 process_request
这是自定义中间件MD2中的 process_request

这是试图函数。。。。。
这是自定义中间件MD2中的 process_response
这是自定义中间件MD1中的 process_response

看结果可知:

process_response方法是在视图函数之后执行的,并且顺序是MD2比MD1先执行。(此时settings.py中 MD1比MD2先注册)

多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,也就是说第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行。

process_view:

process_view(self, request, view_func, view_args, view_kwargs)

该方法有四个参数

request是HttpRequest对象。

view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)

view_args是将传递给视图的位置参数的列表.

view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。

Django会在调用视图函数之前调用process_view方法。

它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。

给MD1和MD2添加process_view方法:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponseclass MD1(MiddlewareMixin):  def process_request(self,request):print(id(request))   #这个request和视图函数中的request是一样的。打印id可以验证request.s12 = ’哈哈哈‘  #也可以给request对象设置属性,这个属性可以在视图函数调用。print(‘这是自定义中间件MD1中的 process_request’)return HttpResponse(‘阿瑟东’)def process_response(self,reuqest,response)print (‘这是自定义中间件MD1中的 process_response’)return responsedef process_View(self, request, view_func, view_args, view_kwargs):    """        对视图做处理        :param request: 请求对象        :param view_func: 要执行的是与函数对象        :param view_args:        :param view_kwargs:        :return:        """    # view_func(request) #django会在执行视图函数之前在执行一遍。     print(‘这是自定义中间件MD1中的 process_view方法...’)    # return HttpResponse("嘿嘿嘿")     class MD2(MiddlewareMixin):#定义多个中间件,def process_request(self, request): print("这是自定义中间件MD2中的 process_request")def process_response(self,reuqest,response)print (‘这是自定义中间件MD2中的 process_response’)return response    def process_View(self, request, view_func, view_args, view_kwargs):    #   view_func(request) #django会在执行视图函数之前在执行一遍。       print(‘这是自定义中间件MD1中的 process_view方法...’)    #   return HttpResponse("嘿嘿嘿")

访问index视图函数,看一下输出结果:

这是自定义中间件MD1中的 process_request
这是自定义中间件MD2中的 process_response
这是自定义中间件MD1中的 process_view方法...
这是自定义中间件MD1中的 process_view方法...
这是视图函数。。。。。
这是自定义中间件MD2中的 process_response
这是自定义中间件MD1中的 process_response

process_view方法是在process_request之后,视图函数之前执行的,执行顺序按照MIDDLEWARE中的注册顺序从前到后顺序执行的

process_exception:

process_exception(self, request, exception)

该方法两个参数:

一个HttpRequest对象

一个exception是视图函数异常产生的Exception对象。

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

给MD1和MD2添加上这个方法:

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponseclass MD1(MiddlewareMixin):  def process_request(self,request):print(id(request))   #这个request和视图函数中的request是一样的。打印id可以验证request.s12 = ’哈哈哈‘  #也可以给request对象设置属性,这个属性可以在视图函数调用。print(‘这是自定义中间件MD1中的 process_request’)return HttpResponse(‘阿瑟东’)def process_response(self,reuqest,response)print (‘这是自定义中间件MD1中的 process_response’)return responsedef process_View(self, request, view_func, view_args, view_kwargs):"""对视图做处理:param request: 请求对象:param view_func: 要执行的是与函数对象:param view_args::param view_kwargs::return:"""# view_func(request) #django会在执行视图函数之前在执行一遍。print(‘这是自定义中间件MD1中的 process_view方法...’)# return HttpResponse("嘿嘿嘿")def process_exception(self, request, exception):print("这是自定义中间件MD1中的 process_exception 方法...")print(exception)return HttpResponse("出异常了,我不想让你看黄色页面1")class MD2(MiddlewareMixin):#定义多个中间件,def process_request(self, request): print("这是自定义中间件MD2中的 process_request")def process_response(self,reuqest,response)print (‘这是自定义中间件MD2中的 process_response’)return responsedef process_View(self, request, view_func, view_args, view_kwargs):#   view_func(request) #django会在执行视图函数之前在执行一遍。print(‘这是自定义中间件MD1中的 process_view方法...’)#   return HttpResponse("嘿嘿嘿")     def process_exception(self, request, exception):print("这是自定义中间件MD1中的 process_exception 方法...")print(exception)return HttpResponse("出异常了,我不想让你看黄色页面1")         

如果视图函数中无异常,process_exception方法不执行。

想办法,在视图函数中抛出一个异常:

def index(request):print("app01 中的 index视图")raise ValueError("这是一个异常....")return HttpResponse("O98K")

看输出结果:

这是自定义中间件ND1中的process——request
这是自定义中间件ND2中的process——request
这是自定义中间件MD1中的 process_view方法...
这是自定义中间件MD2中的 process_view方法...
这是试图函数
这是自定义中间件MD2中的 process_exception 方法...
这是一个异常...
这是自定义中间件ND2中的process——response
这是自定义中间件ND1中的process——response

注意,这里并没有执行MD1的process_exception方法,因为MD1中的process_exception方法直接返回了一个响应对象。

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 HttpResponseclass Md1(MiddlewareMixin):def process_request(self,request):request.s12='asdf'print('这是自定义中间件ND1中的process——request')def process_response(self,request,response):print('这是自定义中间件ND1中的process——response')return responsedef process_view(self,request, view_func, view_args, view_kwargs):print('这是自定义中间件MD1中的 process_view方法...')def process_exception(self,request,exception):print('这是自定义中间件MD1中的 process_exception 方法...')print(exception)return HttpResponse("出异常了,我不想让你看黄色页面1")def process_template_response(self,request,response):print("这是MD1 中的process_template_response")return responseclass Md2(MiddlewareMixin):def process_request(self,request):print('这是自定义中间件ND2中的process——request')def process_response(self, request, response):print('这是自定义中间件ND2中的process——response')return responsedef process_view(self, request, view_func, view_args, view_kwargs):print('这是自定义中间件MD2中的 process_view方法...')def process_exception(self, request, exception):print('这是自定义中间件MD2中的 process_exception 方法...')print(exception)return HttpResponse("出异常了,我不想让你看黄色页面1")def process_template_response(self,request,response):print("这是MD2 中的process_template_response")return response

views.py中:

from django.shortcuts import render,HttpResponse# Create your views here.
def index(request):print('这是试图函数')# print(request.s12)# raise Exception('这是一个异常...')def render():print('o98k')return HttpResponse('太绕了...')rep = HttpResponse('ok')rep.render = renderreturn rep# return HttpResponse('ok')

访问index视图,终端输出的结果:

这是自定义中间件ND1中的process——request
这是自定义中间件ND2中的process——request
这是自定义中间件MD1中的 process_view方法...
这是自定义中间件MD2中的 process_view方法...
这是试图函数
这是MD2 中的process_template_response
这是MD1 中的process_template_response
o98k
这是自定义中间件ND2中的process——response
这是自定义中间件ND1中的process——response

从结果看出:

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

 

这就讲完了中间件的五种方法,我们来缕一缕django的执行流程:

django请求完整的生命周期:浏览器先发一个请求,先走wsgi,他按照http协议解析一个收发消息,然后走requestMiddles,如果这些中间件都返回none,就继续往后走,如果返回响应,就走response,然后再url.py文件里找用户访问的路径,拿到视图函数后,走viewMiddle中间件,如果还是都返回none,就执行真正的视图函数,然后走models.py,往数据库里写数据,拿到数据之后,就可以去template去渲染页面了,然后就是生成响应对象了,又通过试图函数里的return返回,然后走ResponseMiddles中间件。如果说在视图函数中有异常,就走exceptionMiddle中间件,然后交给ResponseMiddle。 请求级别的异常处理直接交给ResponseMiddle。

转载于:https://www.cnblogs.com/yb635238477/p/9438517.html

django框架之中间件相关推荐

  1. django框架之中间件 Auth模块

    CBV加装饰器 方式一:装饰器加到想装饰的方法上 方式二:装饰器加到class前面,通过name参数指定被装饰的方法 方式三:重写dispatch(django分发CBV视图函数),直接给dispat ...

  2. Django框架 之 中间件

    Django框架 之 中间件 浏览目录 中间件介绍 自定义中间件 中间件的执行流程 中间件版登录验证 一.中间件介绍 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个 ...

  3. python写数据库中间件_python3开发进阶-Django框架的中间件的五种用法和逻辑过程...

    阅读目录 一.什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出. 每个中间件组件都 ...

  4. django python3会员中心_python3开发进阶-Django框架的自带认证功能auth模块和User对象的基本操作...

    阅读目录 一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: authenticate( ...

  5. Python 之 Django框架( Cookie和Session、Django中间件、AJAX、Django序列化)

    12.4 Cookie和Session 12.41 cookie Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务 ...

  6. Django 框架篇(七) : 中间件 以及 5种方法

    中间件介绍: 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的功 ...

  7. django框架--中间件系统

    目录 零.参考 一.中间件的基本理解 二.中间件的系统定位 三.中间件的配置 四.中间件的执行流程 五.中间件与装饰器之间的思考 六.中间件的应用场景 七.内置中间件 八.总结 零.参考 https: ...

  8. 自学Python第二十二天- Django框架(三) AJAX、文件上传、POST 请求类型之间的转换、多APP开发、iframe、验证码、分页器、类视图、中间件、信号、日志、缓存、celery异步

    Django官方文档 django 使用 AJAX django 项目中也可以使用 ajax 技术 前端 前端和其他 web 框架一样,需要注意的是,django 接收 POST 请求时,需要 csr ...

  9. Django框架学习索引

    索引目录 1.Django介绍与安装 2.Django流程及模式 3.Django基本配置 4.Django模板(Templages) 1.Django的介绍和安装 3.Django框架模式 4.数据 ...

最新文章

  1. python whl大全
  2. 分享5个免费的在线 SQL 数据库环境,简直太方便了!
  3. OpenCV 使用方向梯度直方图估计图像旋转角度
  4. 【centOS】centOS安装图形界面
  5. c语言自动计算时间,C语言 · 计算时间
  6. UnrealVS扩展
  7. Redis--Windos下的安装和使用
  8. 打包vue项目时报错:Expected indentation of 6 spaces but found 10
  9. Android BlueDroid(一):BlueDroid概述
  10. 读完 Effective Java,我整理这 59 条技巧!
  11. 如何以最好的方式实现游戏关卡
  12. 22 个最常用的Python包
  13. CTGU·OJ .特别的幸运数
  14. 免费注册个体户营业执照出证教程
  15. Java-满天繁星案例(2)
  16. python爬虫----爬取网易云音乐
  17. STM32 -- 做一块自己的开发板(STM32F103C8T6)
  18. Word 文字处理学习笔记
  19. fishhook-动态修改MachO文件
  20. flutter enum枚举型

热门文章

  1. 从B站的代码泄露事件中,我们能学到些什么?
  2. 海量微博数据舆情热点挖掘项目难点总结
  3. 安超云生态 | 安超云与数科网维联合推出“医疗全场景档案云共享解决方案”
  4. 文本生成任务常见评估指标
  5. 设置计算机访问权限密码忘了怎么办,电脑上设置的密码忘记了怎么办
  6. python qt5 增加文本框_PyQt5 文本输入框自动补全 QLineEdit
  7. ASCII码与字符移动
  8. nginx pc 端和 手机移动端分离
  9. 汇编语言||基本传送指令MOV的用法详解
  10. 微软欲用Silverlight阻击Flash