目录
权限、频率、过滤、排序、异常处理
权限
#源码分析
# APIView---->dispatch---->initial--->self.check_permissions(request)(APIView的对象方法)
def check_permissions(self, request):
# 遍历权限对象列表得到一个个权限对象(权限器),进行权限认证
for permission in self.get_permissions():
# 权限类一定有一个has_permission权限方法,用来做权限认证的
# 参数:权限对象self、请求对象request、视图类对象
# 返回值:有权限返回True,无权限返回False
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
权限的完整使用
#写一个类,继承BasePermission,重写has_permission方法,里面写逻辑,如果权限通过返回True,否则False
from rest_framework.permissions import BasePermission,重写
class UserPermission(BasePermission):
def has_permission(self, request, view):
user = request.user
if user.type == 1:
return True
else:
return False
#全局配置
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ['app01.utils.permission.UserPermission'],
}
#局部禁用
permission_class = []
#局部使用
from app01.utils.permission import UserPermission
permission_class = [UserPermission,]
内置权限的完整使用
#先登录admin页面,经过SessionAuthentication就会保存token然后经过IsAdminUser效验token,是判断is_staff字段1为True、0为False
#通过则可以访问TestAPIView了
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication
class TestAPIView(APIView):
authentication_classes = [SessionAuthentication,]
permission_classes = [IsAdminUser,]
def get(self,request,*args,**kwargs):
return Response({"status":100,'msg':'成功'})
频率
内置频率限制(未登录用户)
#全局配置、限制未登录用户1分钟访问3次
#views.py
class TestAPIView(APIView):
#需要搭配这两使用,局部禁用
authentication_classes = []
permission_classes = []
def get(self,request,*args,**kwargs):
return Response({"status":100,'msg':'成功'})
#settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle',),
'DEFAULT_THROTTLE_RATES': {'anon': '3/m',}
}
#局部使用
#views.py
from rest_framework.throttling import AnonRateThrottle
class Test2APIView(APIView):
authentication_classes = []
permission_classes = []
throttle_classes = [AnonRateThrottle,]
def get(self,request,*args,**kwargs):
return Response({"status":100,'msg':'成功'})
#settings.py需要配置频率
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {'anon': '3/m',}
}
内置频率限制(登录用户跟未登录用户)
#全局配置,登录用户1分钟访问5次,未登录用户访问3次
#views.py
from rest_framework.throttling import AnonRateThrottle
from rest_framework.throttling import UserRateThrottle
from rest_framework.authentication import SessionAuthentication
class Test2APIView(APIView):
authentication_classes = [SessionAuthentication,]
throttle_classes = [UserRateThrottle,AnonRateThrottle,]
def get(self,request,*args,**kwargs):
print(request.user)
return Response({"status":100,'msg':'成功'})
#settins.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m',
'anon': '5/m',}}
#局部配置
#views.py
from rest_framework.throttling import AnonRateThrottle
from rest_framework.throttling import UserRateThrottle
from rest_framework.authentication import SessionAuthentication
class Test2APIView(APIView):
#搭配认证类、保存登录用户,不然登录了admin页面之后也是匿名用户
authentication_classes = [SessionAuthentication,]
throttle_classes = [UserRateThrottle,AnonRateThrottle,]
def get(self,request,*args,**kwargs):
print(request.user)
return Response({"status":100,'msg':'成功'})
#settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'user': '10/m',
'anon': '5/m',}}
过滤
1 安装pip3 install django-filter(最新版本需要django2.2以上)
2 在app中注册
INSTALLED_APPS = [
'django_filters'
]
3 全局配
#views.py
from rest_framework.generics import ListAPIView
class Test3APIView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
filter_fields = ('age', 'sex')#需要过滤的字段,可以加多个
#settings.py
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
4 局部配,导入的对象不一样,from rest_framework.filters import SearchFilter
#局部过滤
from rest_framework.generics import ListAPIView
from rest_framework.filters import SearchFilter
class Test4APIView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
filter_backends = [SearchFilter]
search_fields = ['name', 'price']
排序
#局部配置
from rest_framework.generics import ListAPIView
from rest_framework.filters import OrderingFilter
from app01.models import Book
from app01.ser import BookSerializer
class BookListAPIView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [OrderingFilter,]
ordering_fields = ('id', 'price')
#使用
http://127.0.0.1:8000/books2/?ordering=-price
http://127.0.0.1:8000/books2/?ordering=price
http://127.0.0.1:8000/books2/?ordering=-id
自定义异常处理
#全局配置
#views.py
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)
if not response:
if isinstance(exc,ZeroDivisionError):
return Response(data={'status':444,'msg':str(exc)},status=status.HTTP_400_BAD_REQUEST)
return Response(data={'status':999,'msg':str(exc)},status=status.HTTP_400_BAD_REQUEST)
else:
Response(data={'status':888,'msg':response.data.get('detail')},status=status.HTTP_400_BAD_REQUEST)
#settings.py
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.app_auth.my_exception_handler',}
#局部使用
在需要的地方
from rest_framework import status
return Response(data={"name": "PrivateIdNotUniqueException", "message": "", "data": None,
"autoAlert": False}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
封装Response对象(重要)
#以后都用自己封装的
from rest_framework.response import Response
class APIResponse(Response):
def __init__(self, code=100,msg='成功',data=None,status=None,headerrs=None,**kwargs):
dic = {'code':code,msg:msg}
if data:
dic = dic['data'] = data
dic.update(kwargs)
super().__init__(data=dic,status=status,headers=headerrs)
#使用
return APIResponse(data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee')
数字后加逗号是元祖
a=(3,) a=3, 这两是一样的
print(type(a))#<class 'tuple'>