DRF-Django rest framework
认证权限频率
1. 限流Throttling
-
可以对接口访问的频次进行限制,以减轻服务器压力
-
一般用于付费购买次数,投票等场景使用
1. 自定义频率类
1. 限制某个用户,某个ip的访问频次
2. 自定义频率类及使用
'''
自定义的限制逻辑
1. 取出访问者ip
2. 判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
3. 循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉
这样列表中只有60s以内的访问时间
4. 判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
5. 当大于等于3,说明一分钟内访问超过三次,返回False验证失败
'''
# 代码演示
from rest_framework.throttling import BaseThrottle
class MyThrottle(BaseThrottle):
# 存用户访问信息的大字典
VISIT_RECORD = {}
def __init__(self):
self.history = None
def allow_request(self,request,view):
# 根据ip进行频率限制,每分钟只能访问3次
# 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])
3. 使用
1. 局部使用
# 在视图类里使用
throttle_classes = [MyThrottles,]
2. 全局使用
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES':['app01.utils.MyThrottles',],
}
2. 内置频率类使用
1. 使用
1. 局部使用
throttle_classes = [auth.MyThrottle,]
2. 全局使用
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES':['app01.auth.MyThrottle',],
}
2. 内置频率类
BaseThrottle: 基类
AnonRateThrottle: 限制匿名用户的访问次数
SimpleRateThrottle:咱么自定义扩写它
ScopedRateThrottle:
UserRateThrottle: 限制登录用户访问次数
3. 扩展内置频率类
# 1. 写一个类,继承SimpleRateThrottle
class MySimpleThrottle(SimpleRateThrottle):
scope = 'xxx'
def get_cache_key(self, request, view):
#以ip限制
return self.get_ident(request)
# 2. setting.py中配置
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES' : {
'xxx':'10/m' # key跟scope对应,value是一个时间
}
}
# 3. 限制匿名用户每分钟访问3次
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m',
}
}
'''使用 `second`, `minute`, `hour` 或`day`来指明周期 可以全局使用 局部使用'''
# 4. 限制登陆用户每分钟访问10次
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m'
}
}
4. 源码分析
继承SimpleRateThrottle ==> allow_request(跟上面自定义的频率类一样)
5. 其它内置频率类
1. AnonRateThrottle
限制未登录用户的频率(根据ip限制)
使用:
-局部使用,全局使用
-setting.py中配置
'DEFAULT_THROTTLE_RATES' : {
'anon':'1/m'
}
2. UserRateThrottle
限制登录用户访问次数 使用User id来区分(根据用户id限制)
使用:
-局部使用,全局使用
-setting.py中配置
'DEFAULT_THROTTLE_RATES' : {
'user':'1/m'
}
3. ScopedRateThrottle
限制用户对于每个视图的访问频次,使用 ip 或 user id
# 示例
class ContactListView(APIView):
throttle_scope = 'contacts'
...
class ContactDetailView(APIView):
throttle_scope = 'contacts'
...
class UploadView(APIView):
throttle_scope = 'uploads'
...
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'contacts': '1000/day',
'uploads': '20/day'
}
}
3. 实例
# 全局配置中设置访问频率
'DEFAULT_THROTTLE_RATES': {
'anon': '3/minute',
'user': '10/minute'
}
# 视图类
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle
class StudentAPIView(RetrieveAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
throttle_classes = (UserRateThrottle,)
2. 过滤排序
1. 内置-第三方过滤Filtering
1. 过滤
筛选查询结果
2. 内置筛选的使用
# 在视图类中配置
filter_backends =[SearchFilter,]
search_fields=('name',) # 表模型中的字段
# 查询的时候
http://127.0.0.1:8000/students/?search=e
3. 第三方扩展的过滤功能
1. 安装第三方过滤模块
pip3 install django-filter
# 注意: 最新版本(2.4.0)要跟django2.2以上搭配
2. 在视图类中配置
filter_backends =[DjangoFilterBackend,]
filter_fields=['name','age']
3. 在配置文件中增加过滤后端的设置
INSTALLED_APPS = [
...
'django_filters', # 需要注册应用,
]
REST_FRAMEWORK = {
...
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
4. 在视图中添加filter_fields属性,指定可以过滤的字段
class StudentListView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
filter_fields = ('age', 'sex')
5. 查询的时候
http://127.0.0.1:8000/students/?name=lqz&age=18
2. 排序功能
对于列表数据,REST framework 提供了 OrderingFilter 过滤器来帮助我们快速指明数据按照指定字段进行排序
使用方法:
在类视图中设置filter_backends,使用 rest_framework.filters.OrderingFilter
过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。
前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。
# 1. 排序
# 在视图类中配置
class StudentListView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
filter_backends =[OrderingFilter,]
ordering_fields=['id','age']
'''
127.0.0.1:8000/books/?ordering=-age
-id 表示针对id字段进行倒序排序
id 表示针对id字段进行升序排序
'''
# 查询的时候
http://127.0.0.1:8000/students/?ordering=-age
# 2. 过滤后再排序
# 在视图类中配置
from rest_framework.generics import ListAPIView
from students.models import Student
from .serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
class Student3ListView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# 因为局部配置会覆盖全局配置,所以需要重新把过滤组件核心类再次声明,否则过滤功能会失效
filter_backends = [OrderingFilter,DjangoFilterBackend]
ordering_fields = ('id', 'age')
filter_fields=['name','age']
# 查询的时候
http://127.0.0.1:8000/students/?name=lqz&age=19&ordering=-age,-id