权限,频率,过滤,异常处理
权限
权限源码分析
- 我们还是从入口点开始
APIView--> dispatch--> initial--> check_permissions
check_permissions源码
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)
)
- 遍历权限对象得到一个个对象,进行权限认证
- 权限类中一定有一个has_permission权限方法,用来做权限认证
- 参数:权限对象self ,请求对象的request, 视图类对象
- 返回值:有权限返回True, 无权限返回False
权限的使用
在写一个类,继承BasePermission,重写has_permission,如果权限通过,就返回True,不通过就返回False
class UserPermision(BasePermission):
def has_permission(self, request, view):
# 不是超级用户就不能访问
# 认证通过,request内就有了user对象,当前的登录用户,取出当前用户
user = request.user
print(user.get_user_type_display())
if user.user_type == 1:
return True
return False
测试数据
# 局部使用超级用户使用
class TestView(APIView):
permission_classes = [UserPermision]
def get(self,request):
return Response("这是测试数据")
# 全局使用
class TestView1(APIView):
def get(self,request):
return Response("这是测试数据")
全局使用要在settings里面配置一下
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.authssssssssssss.MyAuthentication", ],
'DEFAULT_PERMISSION_CLASSES': [
'app01.authssssssssssss.UserPermision',
],
}
# 局部禁用
class TestView2(APIView):
permission_classes = []
def get(self,request):
return Response("这是测试数据")
内置权限
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication
# 内置的权限
class TestView3(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAdminUser]
def get(self,request,*args,**kwargs):
return Response("这是测试数据")
频率
内置的频率限制
使用限制未登录
# 全局使用 限制未登录用户1分钟访问3次
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m',
}
}
##############views.py
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication,BasicAuthentication
class TestView4(APIView):
authentication_classes=[]
permission_classes = []
def get(self,request,*args,**kwargs):
return Response('我是未登录用户')
# 局部使用
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication,BasicAuthentication
from rest_framework.throttling import AnonRateThrottle
class TestView5(APIView):
authentication_classes=[]
permission_classes = []
throttle_classes = [AnonRateThrottle]
def get(self,request,*args,**kwargs):
return Response('我是未登录用户,TestView5')
使用限制登录用户
# 需求:未登录用户1分钟访问5次,登录用户一分钟访问10次
全局:在setting中
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m',
'anon': '5/m',
}
局部配置:
在视图类中配一个就行
过滤
#1 安装:pip3 install django-filter
#2 注册,在app中注册
#3 全局配,或者局部配
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
#4 视图类
class BookView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_fields = ('name',) #配置可以按照哪个字段来过滤
排序
from rest_framework.filters import OrderingFilter
class BooK1View(ListAPIView):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
filter_backends = [OrderingFilter]
ordering_fields = ('id',"name")
# 使用:
http://127.0.0.1:8000/books2/?ordering=name
http://127.0.0.1:8000/books2/?ordering=-id
异常处理
from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status
def my_exception_handler(exc, context):
response=exception_handler(exc, context)
# 两种情况,一个是None,drf没有处理
#response对象,django处理了,但是处理的不符合咱们的要求
# print(type(exc))
print(type(exc))# 这里可以打印出更详细的错误信息
if isinstance(exc,ZeroDivisionError):
return Response(data={'status':777,'msg':"o的错误"},status=status.HTTP_400_BAD_REQUEST)
if not response:
return Response(data={'status':999,'msg':str(exc)},status=status.HTTP_400_BAD_REQUEST)
else:
return Response(data={'status': 888, 'msg': response.data.get('detail')}, status=status.HTTP_400_BAD_REQUEST)
封装Response对象
# 以后都用自己封装的
class APIResponse(Response):
def __init__(self,code=100,msg='成功',data=None,status=None,headers=None,**kwargs):
dic = {'code': code, 'msg': msg}
if data:
dic = {'code': code, 'msg': msg,'data':data}
dic.update(kwargs)
super().__init__(data=dic, status=status,headers=headers)
# 使用
return APIResponse(data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee')
return APIResponse(data={"name":'lqz'})
return APIResponse(code='101',msg='错误',data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee',header={})
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步