ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

DRF---自定义频率类,权限和频率执行源码分析,全局异常处理(重要),自动生成接口文档和RBAC介绍(面试)

2022-06-22 18:32:43  阅读:145  来源: 互联网

标签:自定义 ip self request --- 源码 频率 权限 history


目录

自定义频率类


自定义的逻辑

​ -(1)取出访问者ip {192.168.1.12:[访问时间3,访问时间2,访问时间1],192.168.1.12:[],192.168.1.14:[]}
​ -(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
​ -(3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
​ -(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
​ -(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败

代码实现

from rest_framework.throttling import BaseThrottle
class MyThrottling():
    VISIT_RECORD = {}

    def __init__(self):
        self.history = None
    def allow_request(self, request, view):
        # (1)取出访问者ip
        ip = request.META.get('REMOTE_ADDR')
        import time
        ctime = time.time()
        # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
        if ip not in self.VISIT_RECORD:
            self.VISIT_RECORD[ip] = [ctime, ]
            return True
        self.history = self.VISIT_RECORD.get(ip)
        # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        while self.history and ctime - self.history[-1] > 60:
            self.history.pop()
        # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        if len(self.history) < 3:
            self.history.insert(0, ctime)
            return True
        else:
            return False

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

权限,频率执行源码分析(了解)


权限源码执行流程

# APIView的dispatch---》self.initial(request, *args, **kwargs)---》415行self.check_permissions(request)--->
    def check_permissions(self, request):
        for permission in self.get_permissions(): #配在视图类上的权限类列表对象
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request,
                    message=getattr(permission, 'message', None),
                    code=getattr(permission, 'code', None)
                )

频率源码执行流程

# APIView的dispatch---》self.initial(request, *args, **kwargs)---》416行self.check_throttles(request)--->
  def check_throttles(self, request):
        throttle_durations = []
        for throttle in self.get_throttles(): # 配在视图类上频率类列表 频率类的对象
            if not throttle.allow_request(request, self):
                throttle_durations.append(throttle.wait())
        if throttle_durations:
            durations = [
                duration for duration in throttle_durations
                if duration is not None
            ]

            duration = max(durations, default=None)
            self.throttled(request, duration)
            
# 你写的频率类一定要重写allow_request,返回True就是没有频率限制住,返回False就是被频率限制了

# 咱们第一天写的,继承SimpleRateThrottle---》它肯定重写了allow_request---》今天写的逻辑跟源码一样
SimpleRateThrottle---》allow_request---》
	def __init__(self):
        if not getattr(self, 'rate', None):
            # self.rate 现在是  '3/m'
            self.rate = self.get_rate()
        # 3                   60
        self.num_requests, self.duration = self.parse_rate(self.rate)
    def allow_request(self, request, view):
        if self.rate is None:  # 只要配在文件配了,它就有值,在init中
            return True

        # 现在的唯一字符串
        # ip地址
        self.key = self.get_cache_key(request, view)
        if self.key is None:
            return True

        # [时间2,时间1]
        self.history = self.cache.get(self.key, [])
        self.now = self.timer()
        while self.history and self.history[-1] <= self.now - self.duration:
            self.history.pop() #把所有超过60的数据都剔除,self.history只剩60s以内的访问时间
        if len(self.history) >= self.num_requests:  #大于等于配置的数字3 
            return self.throttle_failure() # return False
        return self.throttle_success()  # 把当前时间插入,retrun True

全局异常处理(重要)


drf配置文件中,已经配置了,但是它不符合咱们的要求。

drf的配置文件:

'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',

如果抛了异常,就会执行exception_handler函数,重新写一个函数,如果出了异常,执行我们的函数。drf默认的异常处理,只处理了drf自己的异常:所有drf中抛的异常,都有detail,django的异常,抛出很长的xml数据。

第一步:写一个函数

from rest_framework.views import exception_handler
from rest_framework.response import Response
def common_exception_handler(exc, context):
    # 正常来讲,在这里需要记录日志---》如何在django中记录日志后面讲
    # 日志记录,越详细越好:哪个用户(id,ip),在什么时间,执行哪个视图函数时报了错,请求地址是什么
    print(context['view'])  #视图类的对象
    print(context['request']) #当前请求的对象----》ip,用户id,当前时间,请求地址来
    view=context['view']
    request=context['request']
    print('ip地址为:%s的用户,访问:%s 视图类,报错了,请求地址是:%s'%(request.META.get('REMOTE_ADDR'),str(view),request.path))

    response=exception_handler(exc, context)
    if response: # 这是drf的异常,其实人家已经处理了,但是不符合我的格式  {code:999,msg:错误}
        res=Response({'code':999,'msg':response.data.get('detail')})
    else:
        # res=Response({'code':998,'msg':'服务器错误,请联系系统管理员'})
        res=Response({'code':998,'msg':str(exc)})

    return res

第二步:把函数配置在配置文件中

REST_FRAMEWORK = {
    # 自己写的全局异常捕获
        'EXCEPTION_HANDLER': 'app01.exceptions.common_exception_handler',
    }

自动生成接口文档


后端人员,写好接口,提供接口文档给前端用。

如何编写接口文档:

​ - 使用word写,md写----》提交到git上

​ - 公司有接口文档平台---》后端人员在文档平台录入数据---》公司自己开发,yapi(百度开源),第三方

​ - https://zhuanlan.zhihu.com/p/366025001 自己搭建yapi

​ - https://www.showdoc.com.cn/ 第三方平台

​ - 自动生成接口文档---》项目写好了,一键生成接口文档----》一键生成---》导出---》导入到yapi

drf中自动生成接口文档

可以通过第三方插件coreapi,swagger(更通用一些,go,java)来实现。

先下载:pip3 install coreapi

在项目中配置:

# -加入路由:
from rest_framework.documentation import include_docs_urls
        urlpatterns = [
            path('docs/', include_docs_urls(title='站点页面标题'))
        ]
# -配置文件中配置 
REST_FRAMEWORK = {
         'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',

        }
-尽管写接口,写注释,会自动生成

RBAC介绍(面试)


RBAC 是基于角色的访问控制(Role-Based Access Control )。

在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。

这种设计,在公司内部系统用的多,对外的系统基本不用。

  • 权限:真正的权限,比如发工资,招人,申请测试机
  • 角色:(组,部门) 角色下有很多员工
  • 用户:一个个的人
  • 用户和角色关系是多对多,中间表
  • 权限和角色关系是多对多,中间表
  • 权限和用户的中间表

前后端分离项目控制权限在权限类中。

前后端混合:

​ -django框架在公司里用的很多,写内部项目,肯定要用权限控制,用的就是rbac,自己实现一套,django内置了后台管理,自带rbac(admin+auth)

​ -基于django的admin二次开发
​ -美化:xadmin(基本不用了,2.x以后django不兼容多,作者弃坑了)
​ -simpleui:

​ -django+drf+vue=djagnovueadmin 一款前后端分离的自带rbac的后台管理框架

django的admin基于rbac

-auth_user  #用户表
-auth_permission #权限表
-auth_group  #组,角色表
    
-auth_user_groups   # 用户和组中间表
-auth_group_permissions  #组和权限中间表
-auth_user_user_permissions #用户和权限中间表

标签:自定义,ip,self,request,---,源码,频率,权限,history
来源: https://www.cnblogs.com/zaoan1207/p/16401885.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有