DRF之认证、权限、限流、过滤、排序、分页、异常处理、生成接口文档
认证
- 全局认证
在配置文件中配置全局默认的认证方案
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':(
'rest_framework.authentication.BasicAuthentication', # 基本认证
'rest_framework.authentication.SessionAuthentication', # session认证
)
}
- 局部认证
在每个视图中通过设置authentication_classess属性来设置
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
class BookInfo(APIView):
authentication_classess = (SessionAuthentication, BasicAuthentication)
- 认证失败的返回值
- 401 Unauthorized 未认证
- 403 Permission Denied 权限被禁止
权限
-
提供的权限
1.AllowAny 允许所有用户
2.IsAuthenticated 仅通过认证的用户
3.IsAdminUser 仅管理员用户
4.IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取例子:
配置文件为上面全局认证的配置信息
具体的视图如下:
from rest_framework.response import Response
from booktest.models import BookInfo,HeroInfo
from .serializers import BookInfoModelSerializer
# 认证需要的库
from rest_framework.viewsets import ViewSet,GenericViewSet,ReadOnlyModelViewSet,ModelViewSet
from rest_framework.decorators import action # 自定义视图的路由
from rest_framework.permissions import IsAdminUser,AllowAny,IsAuthenticated,IsAuthenticatedOrReadOnly
class BookViewSet( ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
permission_classes = [IsAuthenticated] # 只有通过认证的用户
假如没通过认证的用户访问api时,出现如下:
这里选择的认证条件为:
permission_classes = [IsAuthenticated] # 只有通过认证的用户
- 自定义权限
如果需要自定义权限,需要继承rest_framework.permissions.BasePermission父类,并实现以下两个任何一个方法或全部
- .has_permission(self, request, view)
是否可以访问视图,view表示当前视图对象 - .has_object_permission(self, request, view, obj)
是否可以访问数据对象, view表示当前视图,obj为数据对象例如:class MyPermission(BasePermission): def has_object_permission(self, request, view, obj): '''控制obj对象的访问权限,此案例拒绝所有对对象的访问''' return False class BookInfoViewSet(ModelViewSet): queryset = BookInfo.objects.all() serializer_class = BookInfoSerializer permission_classes = [IsAuthenticated, MyPermission]
限流Throttling
可以对接口访问的频次进行限制,以减轻服务器压力。
- 全局的配置
REST_FRAMEWORK = {
...
'DEFAULT_THROTTLE_CLASSES':( # 限流配置
'rest_framework.throttling.AnonRateThrottle', # 匿名用户
'rest_framework.throttling.UserRateThrottle', # 登录用户
),
'DEFAULT_THROTTLE_RATES':{ # 限流频次
'anon':'10/day', # 匿名频次
'user':'15/day' # 登录用户频次
}
}
可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES 进行全局配置
DEFAULT_THROTTLE_RATES 可以使用 second,minute,hour,day等来指定周期
也可以在具体视图中通过throttle_classess属性来配置
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
class BookInfoView(APIView):
throttle_classes = (UserRateThrottle,)
...
- 可选限流类
1)AnonRateThrottle
限制所有匿名未认证用户,使用IP区分用户
使用 DEFAULT_THROTTLE_RATES[‘anon’] 来设置频次
2)UserRateThrottle
限制认证用户, 使用 User id 来区分
使用 DEFAULT_THROTTLE_RATES[‘user’] 来设置频次
3)ScopedRateTHrottle
限制用户对于每个视图的访问频次,使用id或者user id.
例如
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES':( # 限流配置
'rest_framework.throttling.ScopedRateThrottle', #自定义限制
),
'DEFAULT_THROTTLE_RATES':{ # 限流频次
'seven': '7/day' #指定的视图访问次数限流
}
}
在视图中指定自定的限流
class HeroViewSet( ModelViewSet):
queryset = HeroInfo.objects.all()
serializer_class = HeroInfoModelSerializer
throttle_scope = 'seven' # 指定此视图限流次数
过滤Filtering
对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-filter扩展来增强支持
pip install django-filter
在配置文件中增加过滤设置
INSTALLED_APPS = [
...
#过滤设置
'django_filters',
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
在视图中添加filter_fields属性,指定可以过滤的字段
class HeroViewSet( ModelViewSet):
queryset = HeroInfo.objects.all()
serializer_class = HeroInfoModelSerializer
throttle_scope = 'seven' # 指定此视图限流次数
filter_fields = ['hname', 'hcomment'] # 指定可以过滤的字段
排序
对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序
- 使用方法
在类视图中设置子filter_backends, 使用 rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串中检查是否包含ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。
前端 可以 传递的ordering参数的可选字段值需要在 ordering_fields中指明
例如:
from rest_framework.filters import OrderingFilter # 排序过滤
class HeroViewSet(ModelViewSet):
queryset = HeroInfo.objects.all()
serializer_class = HeroInfoModelSerializer
throttle_scope = 'seven' # 指定此视图限流次数
# filter_fields = ['hname', 'hcomment'] # 指定可以过滤的字段
filter_backends = [OrderingFilter] # 排序过滤
ordering_fields = ['id', 'hname'] # 可排序查询的字段
查询语法:
http://127.0.0.1:8000/book/heros/?ordering=-id
分页Pagination
REST framework提供了分页支持
- 我们可以在配置文件中设置全局的分页方式, 如:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE':100
}
- 通过自定义的Pagination类,来为视图类加不同的分页行为,在视图中通过 pagination_class属性来指明
可选分页器
1)PageNumberPagination
引入 from rest_framework.pagination import PageNumberPagination
创建继承PageNumberPagination的类 (LargeResultsSetPagination)
在对于的视图类中 使用 pagination_class = LargeResultsSetPagination
参数
1. page_size = 6 # 每个页的数目
2. page_query_param = ‘page’ # 前端发送的页数关键字名,默认为"page"
3. page_size_query_param = ‘page_size’ # 前端发送的每页数目关键字名, 默认为None
4. max_page_size = 7 # 前端最多能设置的每页数量
前端访问网址形式:
http://127.0.0.1:8000/book/books/?page=2&page_size=8
视图代码
class LargeResultsSetPagination(PageNumberPagination):
page_size = 6 # 每个页的数目
page_query_param = 'page' # 前端发送的页数关键字名,默认为"page"
page_size_query_param = 'page_size' # 前端发送的每页数目关键字名, 默认为None
max_page_size = 7 # 前端最多能设置的每页数量
class BookViewSet( ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
permission_classes = [IsAuthenticated] # 只有通过认证的用户
throttle_scope = 'seven' # 指定此视图限流次数
pagination_class = LargeResultsSetPagination
2)LimitOffsetPagination
在offset指定的数值向后偏移limit个数量
参数
- default_limit = 5 # 默认限制,默认值与PAGE_SIZE 设置一致
- limit_query_param = ‘limit’ # limit参数名 默认为"limit"
- offset_query_param = ‘offset’ # offset参数名,默认为’offset’
- max_limit = 7 # 最大limit限制,默认为None
代码展示:
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
class LimitOffset(LimitOffsetPagination):
default_limit = 5 # 默认限制,默认值与PAGE_SIZE 设置一致
limit_query_param = 'limit' # limit参数名 默认为"limit"
offset_query_param = 'offset' # offset参数名,默认为'offset'
max_limit = 7 # 最大limit限制,默认为None
前端访问格式:
http://127.0.0.1:8000/book/books/?limit=8&offset=3
异常处理
REST framework提供了异常处理,我们可以自定义异常处理函数
在项目根路径下创建 exceptions.py文件,进行添加异常捕获
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework import status
from django.db import DatabaseError
from rest_framework.response import Response
'''在DRF的异常捕获基础增加数据库的异常捕获'''
def exception_handler(exc, context):
# 先用户DRF自带的异常捕获去拦截 , 这里的drf_exception_handler就是rest_framework.views中的exception_handler,起的别名
response = drf_exception_handler(exc, context)
if response is None:
view = context['view']
if isinstance(exc, DatabaseError):
print('[%s]:%s'%(view,exc))
response = Response({'detail':'服务器内部错误'},status=status.HTTP_507_INSUFFICIENT_STORAGE)
return response
修改配置文件
REST_FRAMEWORK = {
...
# 修改捕获异常函数
#'EXCEPTION_HANDLER':'my_project.my_app.utils.custom_exception_handler'
'EXCEPTION_HANDLER':'exceptions.exception_handler'
}
自动生成接口文档
自动接口文档能生成的是继承自APIView及其子类的视图
- 安装依赖(需要coreapi库的支持)
pip install coreapi
- 设置接口文档访问路径
(在总路由中添加接口文档路径,
文档路由对应的视图配置为 rest_framework.documentation.include_docs_urls,
参数 title为接口文档网站标题)
from django.contrib import admin
from django.urls import path,include
from rest_framework.documentation import include_docs_urls
urlpatterns = [
...
path(r'docs/',include_docs_urls(title='API文档')),
...
]
3.增加文档描述信息(在模型类中增加’’’ ‘’'对api的说明)
class BookViewSet( ModelViewSet):
'''
list:
返回所有图书信息77
create:
增加图书
'''
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
permission_classes = [IsAuthenticated] # 只有通过认证的用户
throttle_scope = 'seven' # 指定此视图限流次数
pagination_class = LimitOffset
- 可能会报错(AttributeError: ‘AutoSchema’ object has no attribute ‘get_link’),在配置文件中添加如下
REST_FRAMEWORK = {
...
# 重新指定schema_class的配置(接口文档)
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
}
谢谢观看~