zoukankan      html  css  js  c++  java
  • Django REST framework之节流组件实例以及源码流程分析

    抛出问题

    对访问的频率进行控制(当然只是在一定程度上限制,若客服端换IP,疯狂注册账号没治)

    通过获取用户的IP,实现一分钟内,只能访问三次。实际生产中应该记录放在数据库,或者放在缓存,或者放在文件中等等,我把记录直接放在这里,占用内存不说,还有就是服务端从启系统的话,记录全丢失。

    视图路由与认证权限相同。

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 from rest_framework.throttling import BaseThrottle
     5 from rest_framework.throttling import SimpleRateThrottle
     6 import time
     7 
     8 VIST_RECORD = {}
     9 
    10 
    11 class VisitThrottle(BaseThrottle):
    12 
    13     def __init__(self):
    14         self.history = None
    15 
    16     def allow_request(self, request, view):
    17 
    18         """
    19         一分钟访问三次最多
    20         判断是否可以继续访问,频率是否达到最大
    21         :param request:
    22         :param view:
    23         :return: True 可以继续访问 False表示访问频率太高要被限制
    24         1.获取用户IP
    25         """
    26         remote_addr = request.META.get('REMOTE_ADDR')
    27         ctime = time.time()
    28         if remote_addr not in VIST_RECORD:
    29             VIST_RECORD[remote_addr] = [ctime,]
    30             return True
    31         history = VIST_RECORD.get(remote_addr)
    32         self.history = history
    33         while history and history[-1] < ctime - 60:
    34             history.pop()
    35 
    36         if len(history) < 3:
    37             history.insert(0, ctime)
    38             return True
    39 
    40     def wait(self):
    41         """
    42         还需要等多久才能被访问
    43         :return:
    44         """
    45         ctime = time.time()
    46         return 60 - (ctime - self.history[-1])

    当然内置的页帮我们写了这些环节,直接获取过来用即可

     1 class VisitThrottle(SimpleRateThrottle):
     2     scope = "Baidu"
     3 
     4     def get_cache_key(self, request, view):
     5         return self.get_ident(request)
     6 
     7 
     8 class UserThrottle(SimpleRateThrottle):
     9     """
    10     根据当前登录用户的访问次数限制
    11     """
    12     scope = "BaiduUser"
    13 
    14     def get_cache_key(self, request, view):
    15         return request.user.username

    全局配置:

     1 REST_FRAMEWORK = {
     2     # 认证
     3     'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.auth.Authticate', ],
     4     # 'DEFAULT_AUTHENTICATION_CLASSES': [],  # AnonymousUser None配置文件中有
     5     # 'UNAUTHENTICATED_USER': lambda: '匿名用户',
     6     # 'UNAUTHENTICATED_USER': None,
     7     # 'UNAUTHENTICATED_TOKEN': None,
     8     # 权限
     9     'DEFAULT_PERMISSION_CLASSES': ['api.utils.permission.Mypermission'],
    10     # 节流 访问频率控制
    11     "DEFAULT_THROTTLE_CLASSES": ['api.utils.throttle.VisitThrottle', ],
    12     "DEFAULT_THROTTLE_RATES": {
    13         "Baidu": '3/m',
    14         "BaiduUser": '10/m',
    15     }
    16 
    17 }

    局部配置:

    1 throttle_classes = [VisitThrottle, ]

    总结:自己定义节流类,在类中实现allow_request(都是这样子若没写前面几个组件都是抛错,看基类),wait两方法,当然wait可以不用写,当然看需求吧!

    源码流程分析

     APIView的dispatch---->封装request----->initial----->self.check_throttles(request)----->allow_request(request, self)(两种情况:True访问频率未达到最高次数,Flase访问频率已经达到最大的次数)

    内置节流类

    BaseThrottle allow_request主逻辑  get_ident获取IP wait超过次数需要多久恢复

    SimpleRateThrottle 适用 跟我上面实现思路差不多 在settings中配置scope即可快捷

    AnonRateThrottle 针对匿名用户的 配置scope = 'anon'

    UserRateThrottle scope = 'user'

    ScopedRateThrottle scope_attr = 'throttle_scope'



  • 相关阅读:
    MySql.Data.dll的版本
    发现一个“佛系记账本”
    坚果云无法同步SVN文件夹
    Kali Linux打开多个终端窗口
    修改Kali Linux终端主题
    Kali Linux搜索软件包
    指定无线网卡监听信道
    解决Aireplay-ng信道问题
    查看干扰进程
    使用Kali官网提供的虚拟机系统
  • 原文地址:https://www.cnblogs.com/Alexephor/p/11296521.html
Copyright © 2011-2022 走看看