DRF路由、认证、权限、频率
目录路由
原来直接在urls.py中直接.as_view()即可
现在
# 一旦视图类继承了ViewSetMixin,则要在路由中配置actions函数
继承了ModelViewSet的视图类
# 自动配置路由
from rest_framework import routers
router = routers.SimpleRouter() # SimpleRouter只会生成两条url
router.register('books','views.BookViewSet') # router.register('前缀','继承自ModelViewSet的视图类','别名')
urlpatterns += router.urls
# 另有
router = routers.DefaultRouter() # DefaultRouter会生成六条url
action的使用
from rest_framework.decorators import action
class BookModelViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
@action(methods=['get',],detail=False) # 向'/get_2/'后缀发送列表中注册的请求时会执行下面函数
def get_2(self,request):
book = self.get_queryset()[:2]
ser = self.get_serializer(book,many=True)
# 如果detail=True,则生成的路由中配置了有名分组pk,需要'/1/get_2'类似的请求,且函数应添加形参pk
认证
# 认证的实现
'''
1.写一个类,继承BaseAuthentication类
from rest_framework.authentication import BaseAuthentication
2.重写authenticate方法,内有认证逻辑,认证通过返回两个值一个值给request.user,另一个值给request.auth,认证失败,抛出AuthenticationFailed异常
3.
'''
源码
# APIView>dispatch>self.initial
self.perform_authentication(request) # >return request.user
class Request #
@property
def user(self):
self._authenticate()
_authenticate():
for authenticator in self.authenticators: # 循环自定义配置的认证类(列表)的认证对象列表
user_auth_tuple = authenticator.authenticate(self) # 这里就用了自己重写的authenticate方法
写认证类
# 应用内新建python文件
from rest_framework.authentication import BaseAuthentication
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
认证类的使用
# 全局使用
from app01.Myauth import MyAuthentication
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'MyAuthentication',
],
}
# 在具体视图类中定义authentica_classes为空列表可以局部禁用
# 局部使用
# 在视图类中定义authentication_classes=[]
权限
源码
# APIView>dispatch>self.initial>self.check_permissions(request)
权限的使用
# 定义权限类
from rest_framework.permissions import BasePermission
class UserAdminPermission(BasePermission):
def has_permission(self, request, view):
user = request.user
# print(user.get_permissions_display())
if user.permissions == 1:
return True
else:
return False
# 局部使用
class NewBooksView(ListAPIView, CreateAPIView):
permission_classes = [UserAdminPermission]
queryset = Book.objects.all()
serializer_class = NewBookModelSerializer
# 全局使用
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'app01.123.UserAdminPermission',
],
}
# 局部禁用
permission_classes = []
内置权限
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAdminUser
class NewBooksView(ListAPIView, CreateAPIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAdminUser]
queryset = Book.objects.all()
serializer_class = NewBookModelSerializer
频率
内置频率
# 全局使用
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle'],
'DEFAULT_THROTTLE_RATES': {
'anon':'3/m', # 限制匿名用户每分钟3次访问
}
}
# 局部使用
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'anon':'3/m', # 限制匿名用户每分钟3次访问
}
}
class NewNewBooksView(ListAPIView, CreateAPIView):
authentication_classes = [AnonRateThrottle]
queryset = Book.objects.all()
serializer_class = NewBookModelSerializer
# 局部禁用
class NewNewBooksView(ListAPIView, CreateAPIView):
authentication_classes = []
# 如果要使用内置登录用户频率限制,则作用的也只是auth_user
频率限制
# 新建频率类继承SimpleRateThrottle以重写其内部的get_cache_key方法,并标明配置名称
from rest_framework.throttling import SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):
scope = 'xxx'
def get_cache_key(self, request, view):# return结果是频率限制的key
return request.META.get('REMOTE_ADDR')
# 局部配置或者全局配置频率类
class BookView(ListAPIView):
throttle_classes = [MyThrottle]
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MYLimitOffsetPagination
# 全局配置对应名称的频率值限制
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'xxx': '3/m',
},
}
自定义频率
from rest_framework.throttling import BaseThrottle
# 自定义频率类,需要重写两个方法,即allow_request、wait
class IPThrottle(BaseThrottle):
visit_dict = {}
def __init__(self):
self.history_list = []
def allow_request(self, request, view):
ip = request.META.get('REMOTE_ADDR')
ctime = time.time()
if ip not in self.visit_dict:
self.visit_dict[ip] = [ctime,]
return True
self.history_list = self.visit_dict[ip]
while True:
if ctime-self.history_list[-1]>60:
self.history_list.pop()
else:
break
if len(self.history_list)<2: # 配置一个周期内的频次限制
self.history_list.insert(0,ctime)
return True
else:
return False
def wait(self):
ctime = time.time()
return 60 - (ctime-self.history_list[-1])
from utils.throttle1 import IPThrottle
class BookView(ListAPIView):
throttle_classes = [IPThrottle]
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MYLimitOffsetPagination
标签:get,self,request,认证,频率,权限,class,路由,DRF
From: https://www.cnblogs.com/missfxy/p/16930677.html