django-rest-framework(五)(节流)

节流

需求:控制用户的访问的频率(10秒中内访问三次)
思想:设立一个全局变量字典,对于匿名用户,将用户的IP作为字典的键;对于登陆用户,将用户的用户名作为字典的键。设置字典的值为一个列表,列表中存储了用户访问的时间,可以通过对列表中的时间进行操作来控制访问频率
代码实现
from django.http import JsonResponse
import time
from rest_framework.views import APIView
from api.models import UserInfo, UserToken

#可以将字典放在缓存中
VISIT_RECODE = dict()

class MyThrottles(object):
    def __init__(self):
        self.history = None

    def allow_request(self, request, view):
        # 获取用户访问的ID
        remote_addr = request._request.META.get('REMOTE_ADDR')
        ctime = time.time()
        # 如果用户是第一次访问,将用户的IP作为字典的键,将用户的第一访问时间作为值放入字典中
        if remote_addr not in VISIT_RECODE:
            VISIT_RECODE[remote_addr] = [ctime, ]

        # 如果用户不是第一次访问,获取列表
        histiory = VISIT_RECODE.get(remote_addr)
        self.history = histiory

        # 筛选出10秒中列表的时间个数
        while histiory and histiory[-1] < ctime - 10:
            histiory.pop()

        # 如果是小于3个,则可以进行访问;否则不能进行访问
        if len(histiory) < 3:
            histiory.insert(0, ctime)
            return True  # 返回True则表示可以进行访问
            # return False # 返回False则表示不能进行访问

    def wait(self):
        ctime = time.time()
        return 10-(ctime - self.history[-1])


class AuthView(APIView):
    '''
    用于登录认证,控制用户的访问的频率(10秒中内访问三次)
    '''
    authentication_classes = []
    throttle_classes = [MyThrottles, ]

    def post(self, request, *args, **kwargs):
        ret = {'code': 1000, 'msg': None}
        try:
            user = request._request.POST.get('username')
            password = request._request.POST.get('password')
            obj = UserInfo.objects.filter(username=user, password=password).first()
            # print(obj)
            if not obj:
                ret['code'] = 1001
                ret['msg'] = '用户名或者密码错误'

            # 创建token
            token = md5(user)
            # logging.info(token)
            print(token)

            UserToken.objects.update_or_create(user=obj, defaults={'token': token})
        except Exception as e:
            print(e)

        return JsonResponse(ret)
节流的全局使用
  • 在setting中配置
REST_FRAMEWORK = {
    #认证配置
    'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.auth.MyAuthtication'],
    # 当认证为匿名用户时,request.user = '匿名用户'/None
    'UNAUTHENTICATED_USER': lambda: '匿名用户', # None
    # 当认证为匿名用户时,request.auth = None
    'UNAUTHENTICATED_TOKEN': None,

    # 权限配置
    'DEFAULT_PERMISSION_CLASSES': ['api.utils.permission.MyPermission'],

    # 节流配置
    'DEFAULT_THROTTLE_CLASSES': [
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值