yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • python基础

  • python高级

  • python模块

  • python设计模式

  • python数据结构与算法

  • django

    • web基础

      • 生成项目依赖的方式
      • web基础
      • 前后端分离介绍
      • restful API设计规范
    • django框架脑图(!必看)

    • django简介
    • MVC及MTV设计模式
    • 搭建django项目环境
    • url路由
    • view视图
    • 模板语法
    • 模型ORM

    • 中间件
      • 链接资料
        • 创建中间件
        • 5个方法,4个特征
        • process_request
        • process_response
        • process_view
        • process_exception
        • process_template_response
        • 自定义中间件
        • 中间件练习
        • 实现限制用户访问的频率 5秒只能访问3次
        • 中间件认证白名单
        • 附:Django请求流程图
    • cookie,session
    • Form和modelform校验器、同源和跨域问题
    • 文件处理

    • django-websocket

    • django测试

    • django-项目

  • django-DRF

  • flask

  • 自己设计开源pip包

  • 自己设计开源项目

  • python小示例

  • python面试题

  • python
  • django
YiZhang-You
2023-05-18
目录

中间件

# 链接资料

  1. 刘江

    中间件 (opens new window)

  2. 博客园-****maple-shaw (opens new window)****

    maple-shaw (opens new window)

# 创建中间件

1. 在app01下新建一个文件夹,Middlewares

2. 在文件夹下,定义中间件的类My_Middlewares.py
    3. 编写中间件,一定要继承MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class MD1(MiddlewareMixin):
    def process_request(self,request):
        print(id(request))
        print("MD1 request")
        return HttpResponse("如果中间键里面有返回值,就不执行后面的视图函数,连中间键后面的也不执行")
4. 注册在settings.py里面的MIDDLEWARE中定义中间件
MIDDLEWARE = [
    'app01.Middlewares.My_Middlewares.MD1',
    # 'app01.Middlewares.My_Middlewares.MD2',
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 5个方法,4个特征

执行时间 执行顺序 参数 返回值

# process_request

process_request(self, request)      #用来处理请求
执行时间:视图函数之前,路由匹配之前
执行顺序:
    按照注册的顺序 顺序执行
参数:
    request请求的对象和视图函数是同一个对象
返回值:
    None 正常流程
    HttpResponse 不执行后面的视图函数,路由匹配,连中间键后面的也不执行,直接返回给浏览器了,直接去执行当前中间件的process_response方法
1
2
3
4
5
6
7
8
9

# process_response

process_response(self, request, response)       #用来响应请求
执行时间:视图函数之后(如果里面有具体的返回值,就会覆盖视图函数里面的返回值,)
执行顺序:
    先按照按照注册的顺序执行, 返回process_response的时候就倒序执行
参数:
    request请求的对象和视图函数是同一个对象
    response响应对象
返回值:
    HttpResponse必须返回
1
2
3
4
5
6
7
8
9

# process_view

process_view(self,request,view_func,view_args,view_kwargs)      #用来处理视图函数
执行时间:视图函数之前,路由匹配之后
执行顺序:
    按照注册的顺序 顺序执行
    process_view方法是在process_request之后,视图函数之前执行的
参数:
    request请求的对象和视图函数是同一个对象
    view_func视图函数
    view_args视图函数的位置参数 ()元组
    view_kwargs视图函数的关键字参数 {}字典
返回值:
    None 正常流程
    HttpResponse
        1.如果process_response 里面是return response
            就返回中间件的process_view方法,视图函数都不执行
        2.如果process_response 里面是return HttpResponse
            执行最后一个中间件的process_response方方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# process_exception

process_exception(self, request, exception)     # 视图函数views有异常的时候,才执行
执行时间(触发条件):视图中有异常才执行
执行顺序:
    按照注册的顺序 倒序执行
参数:
    request请求的对象和视图函数是同一个对象
    exception异常的对象
返回值:
    None 当前的中 间件没有处理异常,交给下一个中间件处理导演,如果 都没有处理导演,django处理异常
    HttpResponse 当前中间件处理了异常,后面的中间件的process_Exception就不执行了,执行最后一个中间件的process_response方法
1
2
3
4
5
6
7
8
9
10

# process_template_response

process_template_response(self, request,response)       #用来处理请求
执行时间(触发条件):视图函数中返回的对象是TemplateResponse对象

执行顺序:
    按照注册的顺序 倒序执行
参数:
    request 请求的对象和视图函数是同一个对象
    response 返回的TemplateResponse对象
返回值:
    HttpResponse TemplateResponse的对象
    过程处理模板的名字 参数
    response.template_name
    response.context_data
1
2
3
4
5
6
7
8
9
10
11
12
13

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

# 自定义中间件

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出

实例一

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("MD1 process_request")
        # ret = HttpResponse("如果中间键里面有返回值,就不执行后面的视图函数,连中间键后面的也不执行")
        # return ret

    def process_response(self, request, response):
        print("MD1 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        # print(request)  # <WSGIRequest: GET '/index/1'>
        # print(view_func)  # <function index at 0x045FBB68>
        # print(view_args)  # ('1',)
        # print(view_kwargs)  # {'id': '2'}
        print("MD1 process_view")
        # return HttpResponse("MD1 process_view")

    def process_exception(self,request,exception): #视图函数views有异常的时候,才执行
        print("异常")

    def process_template_response(self,request,response):
        print("MD1 process_template_response")
        return response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

视图函数

from django.shortcuts import render, HttpResponse
from django.template.response import TemplateResponse

# Create your views here.

def index(request,*args,**kwargs):
    print("index")
    # return render(request,"index.html",{"user":"abcdefg"})
    return TemplateResponse(request,"index.html",{"user":"abcdefg"})
1
2
3
4
5
6
7
8
9

实例二

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class MD1(MiddlewareMixin):

    def process_request(self, request):  # 必须定义这个名字的方法,参数必须写的
        print('MD1请求来了')
        print(request.path)  # 请求路径
        if request.path == '/xx/':
            return None
        else:
            return HttpResponse('你有问题,不让你走了!')  # 后边的都不走了
        # return None # 逻辑正常运行完了  不行默认就是return None

    def process_response(self, request, response):  # 必须定义这个名字的方法,两个参数也是必须写的
        print('MD1响应来了')
        return response  # 必须返回response

class MD2(MiddlewareMixin):

    def process_request(self, request):  # 必须定义这个方法
        print('MD2请求来了')

    def process_response(self, request, response):
        print('MD2响应来了')
        return response
# settins文件中配置
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',
    # 自定义中间件
    'app01.utils.mymiddleware.MD1',
    'app01.utils.mymiddleware.MD2',
]
# 输出
MD1请求来了
/xx/
MD2请求来了
MD2响应来了
MD1响应来了
[20/Nov/2020 09:33:28] "GET /xx/ HTTP/1.1" 200 2
MD1请求来了
/login/
MD1响应来了
[20/Nov/2020 09:33:37] "GET /login/ HTTP/1.1" 200 33
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 中间件练习

# 实现限制用户访问的频率 5秒只能访问3次

#  1. 设置中间件
# 方法一
"""
  print(request.path_info) # 路径名
  # print(request.META) # 更多参数信息
"""
visit_history = {  #历史时间
    # ip:[time,time]
}
print(visit_history)
class Thorttle(MiddlewareMixin):
    def process_request(self, request):

        ip = request.META['REMOTE_ADDR']  # 127.0.0.1
        history = visit_history.get(ip, [])  # 设置参数  {'127.0.0.1': []}
        print("history:", history)
        # 第一次 history  []
        # 第二次 history  [1597467450]
        # 第三次 history  [1597467450,1597467451]
        # 第四次 history  [1597467450,1597467451,1597467453]

        now = time.time()
        new_history = []  # 每循环一次,让它变为空
        for i in history:
            if now - i < 5:  # 如果新的时间减原来的时间小于5秒就,添加到new_history里
                new_history.append(i)

        visit_history[ip] = new_history
        print(visit_history)
        if (len(new_history)) >= 3:
            return HttpResponse("请稍等一下在访问")
        new_history.append(now)

# 方法二
visit_history = {  #历史时间
    # ip:[time,time]
}
class Thorttle(MiddlewareMixin):
    def process_request(self, request):

        ip = request.META['REMOTE_ADDR']  # 127.0.0.1
        history = visit_history.get(ip, [])  # 设置参数  {'127.0.0.1': []}

        now = time.time()
        while history and now-history[-1]>5:
            history.pop()
        if (len(history)) >= 3:
            return HttpResponse("请稍等一下在访问")
        history.append(now)
        visit_history[ip] = history
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  1. 在settings.py里面添加
MIDDLEWARE = [
    'app01.Middlewares.My_Middlewares.Thorttle',
]
1
2
3

# 中间件认证白名单

就可以用中间件的形式代替装饰器了 ,

# mymiddleware.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect
from django.urls import reverse
# 中间件认证
class SessionAuth(MiddlewareMixin):

    def process_request(self, request):
        # 白名单
        print(request.path)
        white_list = [reverse('login'), ]  # 想让哪个路径过就再列表中加入,一般白名单列表放在settings文件中,然后再这里导入后引用,修改时再settings里改就行了
        print(white_list)
        if request.path in white_list:
            return None

        is_login = request.session.get('is_login')  # session认证
        if is_login:
            return None
        else:
            return redirect('login')

# settins
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',
    # 自定义中间件
    # 'app01.utils.mymiddleware.MD1',
    # 'app01.utils.mymiddleware.MD2',
    'app01.utils.mymiddleware.SessionAuth',
]

# views.py
def login(request):

    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        name = request.POST.get('name')
        pwd = request.POST.get('pwd')
        print(name, pwd)
        if name == 'laowang' and pwd == '123':
            # ret = redirect('/home/')
            # ret.set_cookie('is_login', 0)
            # return ret
            request.session['is_login'] = True
            request.session['username'] = 'bo'
            # 1.生成了session_id
            # 2.在cookie里边加上了一个键值对
            # 3.存进django.session表中
            return redirect('/home/')
        else:
            return redirect('login')

def logout(request):
    request.session.flush()  # 清除所有的cookie和session
    return redirect("/login/")

def home(request):
    return render(request, 'home.html')

def index(request):
    return render(request, 'index.html')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

# 附:Django请求流程图

编辑 (opens new window)
验证器
cookie,session

← 验证器 cookie,session→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式