Django——中间件

简介: Django——中间件

Django——中间件

中间件可以介入 Django 的请求和响应的处理过程,修改 Django 的响应数据。中间件的设计为程序开发者提供了一种无侵入式的开发方式,增强 Django 框架的健壮性

中间件可以在 Django 处理视图的不同阶段的干预。

Django 框架中原先内置的一些中间件

MIDDLEWARE = [
    # 主要对安全性访问处理请求,把 http 请求重定向为 https 请求
    'django.middleware.security.SecurityMiddleware',
    # 会话支持
    'django.contrib.sessions.middleware.SessionMiddleware',
    # 检查是否允许浏览器访问类型 , 检查 url 是否需要添加 /
    'django.middleware.common.CommonMiddleware',
    # 跨站点防御保护
    'django.middleware.csrf.CsrfViewMiddleware',
    # 用户认证
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # Cookie 会话支持
    'django.contrib.messages.middleware.MessageMiddleware',
    # 点击劫持保护
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
1、项目启动的时候
2、请求进来的时候需要经过中间件之后才能到后续的路由匹配操作
3、响应到浏览器的时候需要经过中间件
1、认证登录
2、统计访问流量
3、拦截请求:可以限制IP的请求频率或者直接封禁IP

中间件的执行顺序

请求处理之前,中间件根绝配置文件中的配置列表从上往下依次执行;

在请求处理之后,中间件根绝配置文件中的配置列表从下往上依次执行;

1、自定义中间件

定义一个中间件工厂函数,返回一个可以被调用的中间件(闭包)。

中间件的工厂函数必须接收一个可以被调用的 get_response 对象,请求处理。

def simple_middleware(get_response):
    # 这里编写的代码只在 Django 项目启动的时候被执行
    def middleware(request):
        '''
        request : 和我们写的视图函数接收的request数据一致,都是浏览器的请求数据
        '''
        # 这里编写的代码,是在请求处理之前被执行
        response = get_response(request)
        # 这里编写的代码,是在请求处理之后被执行
        return response
        
    return middleware

在应用下新建一个 middleware.py 文件

def simple_middleware(get_response):
    # 这里编写的代码只在 Django 项目启动的时候被执行
    print('初始化 Django')
    def middleware(request):
        '''
        request : 和我们写的视图函数接收的request数据一致,都是浏览器的请求数据
        '''
        # 这里编写的代码,是在请求处理之前被执行
        print('request 请求被处理之前')
        response = get_response(request)
        # 这里编写的代码,是在请求处理之后被执行
        print('request 请求被处理之后')
        return response
    return middleware

定义好中间件之后,需要到配置文件中的 MIDDLEWARE 列表中添加自定义的中间件路径

# 自定义中间件注册
'MiddlewareApp.middleware.simple_middleware',

2、自定义中间件类

自定义中间件类需要继承 MiddlewareMixin

process_request 方法 , 是 Request 预处理函数;这个方法就是在请求处理之前被调用

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMiddleware(MiddlewareMixin):
    def process_request(self , request):
        # request : 用户请求的数据
        # 可以没有返回值:None 中间件就会按照正常的流程执行, 如果配置列表后面还有中间就进入下一个中间件,
        #               否则则进入 url 请求匹配
        print('process_request 预处理函数')
        # 有返回值:HttpResponse 对象,就不执行处理其他的中间件,以及不进行 url 匹配,这里整个请求停止
        #           将这里返回的 HttpResponse 对象响应给浏览器
        return HttpResponse('我是 process_request 响应的数据')

process_response 方法;这个方法是在请求处理之后被调用

def process_response(self , request , response):
        '''
        :param request: 用户请求的数据
        :param response: 是视图返回出来的 HttpResponse 对象
        :return: 必须要有返回值 , 必须返回一个 HttpResponse 对象
                可以返回视图的 response 对象;也可以自定义 HttpResponse 对象 , 则视图中返回值无效
        '''
        print('process_response 执行')
        # return response
        return HttpResponse('我是 process_response 响应的数据')

process_view 方法;这个方法在路由匹配之后 , 视图响应之前

def process_view(self , request , view_func , view_args , view_kwargs):
        '''
        :param request:
        :param view_func:  请求的 url 匹配到的视图函数
        :param view_args: 是给视图传递的参数
        :param view_kwargs: 是给视图传递的参数
        :return: 可以没有返回值;可以返回值匹配到的视图函数,
                            也可以自定义 HttpResponse 对象 , 则视图函数无效
        '''
        print('process_view 执行')
        # return view_func(request)   # ok
        return HttpResponse('我是 process_view 响应的数据')

3、中间件拦截请求

1、限制 IP 访问频率

visit_ip = {}
class IpMiddleware(MiddlewareMixin):
    '''
    1、 获取访问的主机IP
    2、获取到 IP 访问的当前时间
    3、时间间隔为:40s ;超过15次
    '''
    def process_request(self , request):
        # 获取用户访问的主机 IP
        ip = request.META.get('REMOTE_ADDR')
        # 获取 IP 访问的当前时间
        visit_time = time.time()
        # 数据保存格式{IP:[访问时间,……],IP2:[访问时间,……]……}
        # 判断 IP 是否在字典中存在 , 如果存在则这个 IP 不是第一次访问
        # 否则 这个 IP 是第一次访问
        if ip not in visit_ip:
            visit_ip[ip] = [visit_time]
        # ip 在字典中,将访问时间间隔为 大于40s的进行删除时间记录
        old_time = visit_ip.get(ip)
        for t in old_time:
            # 如果列表时间和当前访问时间超过 40s 则清除掉
            if visit_time - t > 40:
                old_time.remove(t)
        # 判断时间列表中记录是否有超过 15 次
        # 没有超过,进行记录当前的访问时间
        # 超过,限制当前 IP 访问
        if len(old_time) < 15:
            old_time.insert(0 , visit_time)
        else:
            return HttpResponse("您别累着了 , 休息一下吧!!!!")

2、禁止 IP 访问

black_ip = {}   # {IP:count}
visit_ip = {}
class IpMiddleware(MiddlewareMixin):
    '''
    1、 获取访问的主机IP
    2、获取到 IP 访问的当前时间
    3、时间间隔为:40s ;超过 5次
    4、保存用户的不良行为记录次数 , 超过 3
    '''
    def process_request(self , request):
        # 获取用户访问的主机 IP
        ip = request.META.get('REMOTE_ADDR')
        ## 从数据库中取出ip进行判断(ip) , 数据库中有则表示已经拉黑 , 没有则表示正常
        # 检查 IP 是否被拉黑
        black_num = black_ip.get(ip , 0)
        if black_num > 3:
            ## 将 ip 拉黑保存到数据库中
            return HttpResponse(status=404)
        # 获取 IP 访问的当前时间
        visit_time = time.time()
        # 数据保存格式{IP:[访问时间,……],IP2:[访问时间,……]……}
        # 判断 IP 是否在字典中存在 , 如果存在则这个 IP 不是第一次访问
        # 否则 这个 IP 是第一次访问
        if ip not in visit_ip:
            visit_ip[ip] = [visit_time]
        # ip 在字典中,将访问时间间隔为 大于40s的进行删除时间记录
        old_time = visit_ip.get(ip)
        for t in old_time:
            # 如果列表时间和当前访问时间超过 40s 则清除掉
            if visit_time - t > 40:
                old_time.remove(t)
        # 判断时间列表中记录是否有超过 15 次
        # 没有超过,进行记录当前的访问时间
        # 超过,限制当前 IP 访问
        if len(old_time) < 5:
            old_time.insert(0 , visit_time)
        else:
            # 保存累计不良行为记录次数
            black_ip[ip] = black_num + 1
            return HttpResponse("您别累着了 , 休息一下吧!!!!")


相关文章
|
1月前
|
中间件 程序员 开发工具
Django实践-08中间件的应用
Django实践-08中间件的应用
Django实践-08中间件的应用
|
17天前
|
缓存 监控 中间件
探究Django中间件的神奇:功能、应用场景和核心方法
在Django中,中间件是一个强大的概念,它们提供了一种灵活的方式来处理请求和响应。本文将探讨Django中间件的基本概念、常见应用场景以及中间件类中的父类和核心方法。
|
1月前
|
中间件 Python
中间件应用Django Middleware(Python)
【5月更文挑战第3天】中间件应用Django Middleware(Python)
43 6
中间件应用Django Middleware(Python)
|
1月前
|
存储 监控 中间件
使用Django的中间件可以解决哪些问题
【4月更文挑战第25天】Django中间件用于处理用户认证、CSRF防御、点击劫持防护、请求响应修改、自定义需求、全局处理、异常处理、数据压缩、Session管理、URL重写、限流和CORS支持。它们按顺序执行,提供安全性、灵活性及定制功能,优化Web开发体验。
15 0
|
1月前
|
中间件 API 文件存储
Django的扩展包与中间件:增强应用功能的利器
【4月更文挑战第15天】本文介绍了Django的扩展包和中间件,两者用于增强Django应用功能。扩展包是可重用的应用,提供额外功能,如用户认证和API开发。选择合适的扩展包,通过安装、配置,可轻松集成到项目中。中间件则在请求和响应之间执行操作,如身份验证和权限控制。创建中间件类并添加到settings.py中,实现特定功能。扩展包和中间件常结合使用,以实现更复杂的应用需求,提高开发效率和应用性能。
|
1月前
|
缓存 中间件 Python
Python Web 开发: 解释 Django 中的中间件是什么,以及如何使用?
Python Web 开发: 解释 Django 中的中间件是什么,以及如何使用?
|
7月前
|
中间件 Python
25 Django高级- 中间件
25 Django高级- 中间件
30 0
|
10月前
|
中间件 Python
|
10月前
|
中间件 Python
|
19天前
|
消息中间件 存储 NoSQL
阿里开源中间件一览
阿里开源中间件一览
24 2