DAY 69 drf07

1 认证,权限,频率
2 三个组件套路都是一样
-写一个类继承一个基类
   -写方法(authenticate,has_permission,allow_request)
   -频率类:由于我们继承了SimpleRateThrottle,所以不需要写allow_request,重写get_cache_key,返回什么就以什么作为限制条件(ip,用户id)
   -返回ip,父类里又有get_ident
   
   
4  接口--python中不推崇接口---》鸭子类型
-规范子类的行为
   -如何限制子类的行为
  -abc模块
      -通过抛异常的方式限制

 

0 从根上自定义频率类(了解)

class MyThrottling(BaseThrottle):
   VISIT_RECORD = {}  # 记录访问者的大字典

   def __init__(self):
       self.history = None

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

SimpleRateThrottle:跟咱们写的一样,只不过通过配置,可扩展性更高

1 过滤

1 过滤针对于 list,获取所有
2 在请求路径中带过滤条件,对查询结果进行过滤

1.1 内置过滤类的使用

1 在视图类中(必须继承GenericAPIView)
2 写如下
   #配置过滤类
   filter_backends=[SearchFilter,]
   # 配置过滤字段
   search_fields=['name','price']
   
3 浏览的地址:
#查询的时候,所有条件都给search,并支持模糊匹配
http://127.0.0.1:8000/api/book/?search=黑楼梦
http://127.0.0.1:8000/api/book/?search=黑楼梦
           
4 全局使用:在配置文件中配置
REST_FRAMEWORK = {
   'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

1.2 第三方过滤类使用(django-filter)

1 安装(django:2.2, 3.1, 3.2
pip3 install django-filter
   
   
   
1 在视图类中(必须继承GenericAPIView)
2 写如下
   #配置过滤类
   filter_backends=[DjangoFilterBackend,]
   # 配置过滤字段
   filter_fields=['name','price']
   
3 浏览的地址:
http://127.0.0.1:8000/api/book/?price=12&name=黄楼梦
  http://127.0.0.1:8000/api/book/?price=12
       
4 全局使用:在配置文件中配置
REST_FRAMEWORK = {
   'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

自己定义过滤类

1 写一个过滤类
from rest_framework.filters import BaseFilterBackend
class Myfilter(BaseFilterBackend):
   def filter_queryset(self, request, queryset, view):
       name = request.GET.get('name')
       queryset = queryset.filter(name__contains=name)
       return queryset
2 在视图类中配置
## 自己定义的
   filter_backends = [Myfilter, ]

 

总结

1 APIViwe中有哪些类属性
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
   parser_classes = api_settings.DEFAULT_PARSER_CLASSES
   authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
   throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
   permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
2 GenericAPIView中有哪些类属性
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
   pagination_class = api_settings.DEFAULT_PAGINATION_CLASS

 

2 排序

1 在视图类中
   ##排序
   filter_backends = [OrderingFilter, ]
   ordering_fields=['price','name']
2 请求方式:
http://127.0.0.1:8000/api/book/?ordering=-price
  http://127.0.0.1:8000/api/book/?ordering=price
  http://127.0.0.1:8000/api/book/?ordering=-price,-name

 

 

4 异常处理

1 写一个函数
from rest_framework.response import Response
def my_exception_handler(exc, context):
response=exception_handler(exc, context)
print(response)
print(exc)
print(context.get('view'))
print(context.get('request').get_full_path())
if not response: #更新粒度的对异常做一个区分
if isinstance(exc,IndexError):
response=Response({'status':5001,'msg':'越界异常'})
elif isinstance(exc,ZeroDivisionError):
response = Response({'status': 5002, 'msg': '越界异常'})
else:
response= Response({'status': 5000, 'msg': '没有权限'})
# 记录日志
return response
2 在配置文件中配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER':'app01.excepiton.my_exception_handler'
}
3 只要以后视图函数中出了错误,都会返回统一格式

 

5 自动生成接口文档

1 coreapi,swagger
2 pip3 install coreapi
3 使用步骤:
1 在路由中
from rest_framework.documentation import include_docs_urls
urlpatterns = [
path('doc/', include_docs_urls(title='路飞项目接口文档')),
]
2 在配置文件中
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
3 在视图类中方法上加注释即可
4 如果是ModelViewSet
"""
list:
返回图书列表数据,通过Ordering字段排序

retrieve:
返回图书详情数据

latest:
返回最新的图书数据

read:
查询单个图书接口
"""
5 字段描述,写在models的help_text上
原文地址:https://www.cnblogs.com/DEJAVU888/p/14893777.html