drf的 认证 权限节流 版本 控制实例

由于未提供博客具体内容,无法生成包含关键信息的摘要。
# Create your views here.
import time

from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
from rest_framework.versioning import BaseVersioning
from rest_framework.views import APIView

visit_records = {}


class MyBaseVersioning(BaseVersioning):
    """
    版本控制
    """
    versions = ['v1', 'v2']

    def determine_version(self, request: Request, *args, **kwargs):
        version = request.query_params.get('version')
        if version not in self.versions:
            raise exceptions.APIException(detail={'msg': '版本不正确'})
        return version


class MyScopedRateThrottle(SimpleRateThrottle):
    """
    节流控制(继承自drf框架实现)
    """
    scope = 'visit'
    THROTTLE_RATES = {
        'visit': '6/m',  # 每分钟访问6次
    }

    def get_cache_key(self, request, view):
        return request.META.get('REMOTE_ADDR')


class MyThrottle(BaseThrottle):
    """
    节流控制(自定义)
    """

    def allow_request(self, request: Request, view):
        # 拿到访问的IP
        ip = request.META.get('REMOTE_ADDR')
        # 访问记录
        # {ip: [timestamp1, timestamp2]}
        now = time.time()
        if ip not in visit_records.keys():
            # 如果是第一次访问就将ip加入到访问记录中
            visit_records.setdefault(ip, [now])
        # 获取该ip的访问记录
        history = visit_records.get(ip)
        # 如果记录中最先一次的访问时间 超出频率 则移除
        if now - history[-1] > 10.0:
            # 移除过期的访问记录
            history.pop()
        # 判断是否可以访问
        if len(history) < 5:
            # 更新该ip的访问时间记录
            visit_records.get(ip).insert(0, now)
            return True
        return False


class MyPermission(BasePermission):
    """
    权限控制
    """

    def has_permission(self, request, view):
        # 抛出异常或者返回False 表示没有权限
        # raise exceptions.PermissionDenied(detail={'msg': '没有权限哦'})
        # return False
        # 返回True 表示有权限
        return True


class MyAuthentication(BaseAuthentication):
    """
    认证控制
    """

    def authenticate(self, request: Request):
        token = request.query_params.dict().get('token')
        if not token:
            # 第一种结果: 抛出异常,认证失败,并终止向后认证
            raise exceptions.AuthenticationFailed(detail={'msg': '认证失败'})
        if token == '123':
            # 第二种结果: 返回tuple,认证成功,并终止向后认证
            return 'abel', token
        # 第三种结果: 返回None,不进行任何认证,继续向后认证
        return None


class TestView(APIView):
    # 配置认证控制类
    authentication_classes = [MyAuthentication]
    # 配置权限控制类
    permission_classes = [MyPermission]
    # 配置节流控制类
    throttle_classes = [MyScopedRateThrottle]
    # 配置版本控制类  注意此处是单个的类 而不是列表
    versioning_class = MyBaseVersioning

    def get(self, requests, *args, **kwargs):
        print(self)
        print('get')
        print(requests)
        data = dict(list(zip('abcd', range(4))))
        return Response(data)

    def post(self, requests, *args, **kwargs):
        print(self)
        print('post')
        print(requests)
        print(requests.FILES)
        file = requests.FILES.dict().get('file')
        for chuck in file.chunks():
            with open('aaa.png', 'wb') as f:
                f.write(chuck)

        data = dict(list(zip('efgh', range(4))))
        return Response(data)

### 节流技术的应用场景 节流(Throttling)是一种优化技术,主要用于限制同一时间段内事件处理器的执行次数。通过这种方式,即使某些事件被频繁触发,也能确保事件处理器在每个时间间隔内仅执行一次[^1]。 #### 常见应用场景 以下是节流技术的一些典型应用领域: 1. **窗口调整(resize)** 当用户调整浏览器窗口大小时,`resize` 事件会被频繁触发。如果不加以限制,可能会导致性能问题。使用节流可以减少回调函数的调用频率,从而提高性能[^4]。 2. **页面滚动监听(scroll)** 类似于 `resize` 事件,在处理页面滚动行为时,`scroll` 事件也可能被高频触发。通过对滚动事件进行节流,可以在不影响用户体验的前提下降低计算开销。 3. **拖拽操作(mousemove)** 在实现 DOM 元素拖拽功能时,鼠标移动事件会持续触发。如果每次触发都重新渲染界面,则可能导致卡顿现象。利用节流可有效缓解这一问题。 4. **按钮点击防护(mousedown/click)** 特定情况下,比如电商网站上的抢购活动,用户可能快速连续点击购买按钮。此时采用节流手段能避免重复提交订单或其他异常情况发生。 #### JavaScript 中的简单实现方式 下面提供了一个基于 JavaScript 的通用节流函数实现示例: ```javascript function throttle(fn, wait) { let timer = null; return function (...args) { if (!timer) { timer = setTimeout(() => { fn.apply(this, args); timer = null; }, wait); } }; } ``` 此代码片段定义了一种简单的节流逻辑:当首次调用该封装后的函数时启动定时器;在此期间再次尝试调用不会生效直到超时期满并重置状态变量。 #### Django REST Framework 中的配置实例 除了前端开发外,在后端框架如 DRF (Django Rest Framework)里同样支持设置 API 请求级别的速率限制策略——即所谓的“节流”。它允许我们既能在全局范围内统一管理访问权限又能针对个别视图单独定制规则[^3]。 例如,要为某个特定 ViewSet 添加每分钟最多允许 10 次请求的约束条件,只需如下所示修改类属性即可完成相应设定: ```python from rest_framework.throttling import UserRateThrottle class ExampleViewSet(viewsets.ModelViewSet): queryset = YourModel.objects.all() serializer_class = YourSerializer class CustomUserThrottle(UserRateThrottle): rate = '10/min' throttle_classes = [CustomUserThrottle] ``` 上述例子展示了如何创建自定义用户级速度控制器,并将其应用于指定资源集合上。 ### 总结 无论是客户端还是服务端编程环境当中,“节流”作为一项重要工具都可以显著改善程序运行效率与稳定性。然而值得注意的一点在于,由于其本质上依赖固定周期来决定何时真正执行目标动作,所以在实际运用过程中还需要依据具体情况灵活调节参数数值以达到最优平衡点[^5]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值