文章目录
1.认证(Authentication)
可以参考官方文档,配置认证内容
1)全局设置
settings.py:
# DRF配置信息
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
# BasicAuthentication:此身份验证方案使用HTTP基本身份验证
'rest_framework.authentication.BasicAuthentication',
# SessionAuthentication:此身份验证方案使用Django的默认会话后端进行身份验证
'rest_framework.authentication.SessionAuthentication',
]
}
2)局部设置
views.py:
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIView
class BookModelViewSet(ModelViewSet):
# 局部认证
authentication_classes = (SessionAuthentication, BasicAuthentication)
...
注意:
1.如果配置了全局和局部,默认使用局部
2.认证失败会有两种可能的返回值:
401 Unauthorized 未认证
403 Permission Denied 权限被禁止
2.权限(Permissions)
权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。
在执行视图的dispatch()方法前,会先进行视图访问权限的判断
在通过get_object()获取具体对象时,会进行对象访问权限的判断
可以参考官方文档,配置权限内容
1)全局设置
settings.py:
# DRF配置信息
REST_FRAMEWORK = {
# 全局认证
'DEFAULT_AUTHENTICATION_CLASSES': [
# BasicAuthentication:此身份验证方案使用HTTP基本身份验证
'rest_framework.authentication.BasicAuthentication',
# SessionAuthentication:此身份验证方案使用Django的默认会话后端进行身份验证
'rest_framework.authentication.SessionAuthentication',
],
# 全局权限
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # 仅通过认证的用户
#'rest_framework.permissions.AllowAny', # 允许所有用户
#'rest_framework.permissions.IsAdminUser', # 仅管理员用户
]
}
运行结果:
普通用户和管理员用户时:
所有用户时:
2)局部设置
class BookModelViewSet(ModelViewSet):
# 局部权限
permission_classes = [AllowAny]
...
运行结果:
注意:如果配置了全局和局部,默认使用局部
使用管理员身份进行登录:
settings.py:
# DRF配置信息
REST_FRAMEWORK = {
# 全局认证
'DEFAULT_AUTHENTICATION_CLASSES': [
# BasicAuthentication:此身份验证方案使用HTTP基本身份验证
'rest_framework.authentication.BasicAuthentication',
# SessionAuthentication:此身份验证方案使用Django的默认会话后端进行身份验证
'rest_framework.authentication.SessionAuthentication',
],
# 全局权限
'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated', # 普通用户
# 'rest_framework.permissions.AllowAny', # 所有用户
'rest_framework.permissions.IsAdminUser', # 管理员用户
]
}
视图中没有局部设置
运行结果:
创建管理员账号:
python manage.py createsuperuser
登录django后台管理:
登录成功之后,再次刷新页面即可:
3.限流(Throttling)
可以对接口访问的频次进行限制,以减轻服务器压力。
可以参考官方文档,配置限流内容
1)全局设置
settings.py:
# DRF配置信息
REST_FRAMEWORK = {
# 全局认证
'DEFAULT_AUTHENTICATION_CLASSES': [
# BasicAuthentication:此身份验证方案使用HTTP基本身份验证
'rest_framework.authentication.BasicAuthentication',
# SessionAuthentication:此身份验证方案使用Django的默认会话后端进行身份验证
'rest_framework.authentication.SessionAuthentication',
],
# 全局限流
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle', # 匿名用户
'rest_framework.throttling.UserRateThrottle' # 认证用户
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/minute', # 匿名用户允许一分钟访问2次
'user': '3/minute' # 认证用户允许一分钟访问3次
},
}
DEFAULT_THROTTLE_RATES 可以使用 second, minute, hour 或day来指明周期。
运行结果:
2)局部设置
class BookModelViewSet(ModelViewSet):
# 局部限流
throttle_classes = [AnonRateThrottle]
...
运行结果:
因为在视图中只设置了对匿名用户的限流 ,所以认证用户无论访问多少次都没有问题。
3)可选限流类
ScopedRateThrottle:限制用户对于每个视图的访问频次
settings.py:
REST_FRAMEWORK = {
# 可选限流
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.ScopedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'downloads': '2/minute',
'uploads': '3/minute'
},
}
views.py:
# 可选限流
class Testview(APIView):
throttle_scope = 'uploads'
def get(self, request):
return Response('testing...')
子路由:
url(r'^test/$', views.Testview.as_view())
运行结果:
4.分页(Pagination)
可以参考官方文档,配置分页内容
1)全局设置
REST_FRAMEWORK = {
# 全局分页
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 2,
}
运行结果:
2)局部设置
class BookModelViewSet(ModelViewSet):
# 局部分页
# pagination_class = LargeResultsSetPagination # ?limit=2 或者 ?offset=1&limit=2
pagination_class = PageNumberPagination # ?page=2
...
运行结果:
我们会发现,page管用,而page_size不管用,这是因为PageNumberPagination源码中page_size_query_param = None,所以会默认使用全局设置中的page_size=2。
如果想使page_size管用,方法一是直接修改源码page_size_query_param = ‘page_size’,此种方法不推荐,推荐使用第二种方法,第二种方法是自定义分页对象
3)自定义分页对象
views.py:
# 自定义分页对象
class MyPageNumberPagination(PageNumberPagination):
# 默认的大小
page_size = 3
# 前端可以指定页面大小
page_size_query_param = 'page_size'
# 页面的最大大小
max_page_size = 5
class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
# 自定义分页对象
pagination_class = MyPageNumberPagination # ?page=2或?page=2&page_size=1
运行结果:
5.过滤(Filtering)
可以参考官方文档,配置过滤内容
对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。
pip install django-filter
1)全局设置
settings.py
REST_FRAMEWORK = {
# 全局过滤
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
在配置文件中增加过滤后端的设置:
INSTALLED_APPS = [
...
'django_filters', # 需要注册应用,
]
运行结果:
全局过滤没有变化
2)局部设置
views.py:
class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
# 局部过滤
filter_backends = [DjangoFilterBackend]
filterset_fields = ['id', 'btitle', "is_delete"]
...
运行结果:
6.排序(OrderingFilter)
对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。
可以参考官方文档,配置过滤内容
局部设置:
class BookModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
# 局部排序
filter_backends = [filters.OrderingFilter] # 导包路径: from rest_framework import filters
ordering_fields = ['id', 'btitle','bread'] #查询格式: ?ordering=-bread,id
...
运行结果:
负号表示倒序
7.异常处理(Exceptions)
通常情况下报错:
views.py:
class Testview(APIView):
def get(self, request):
raise Exception('报错了!!!!')
return Response('testing...')
运行结果:
上面界面报错对用户不好友。,我们需要将界面友好化
class Testview(APIView):
def get(self, request):
raise APIException('报错了!!!!')
#raise ValidationError("报错了!!!")
return Response('testing...')
运行结果:
class TestView(APIView):
def get(self,request):
raise DatabaseError("DatabaseError!!!")
return Response("testing....")
运行结果:
我们查看源码,会发现DatabaseError跟Exception没有关系,为了处理这种情况,我们可以自定义异常处理函数
自定义异常处理
可以参考官方文档,配置过滤内容
my_exception.py:
from rest_framework.views import exception_handler
from rest_framework.response import Response
from django.db import DatabaseError
def custom_exception_handler(exc, context):
# 调用系统方法,处理了APIException的异常,或者其子类异常
response = exception_handler(exc, context)
# 判断response是否有值
if response is not None:
response.data['status_code'] = response.status_code
else:
if isinstance(exc, DatabaseError):
response = Response("数据库大出血")
else:
response = Response("其他异常!")
return response
settings.py:
REST_FRAMEWORK = {
# 全局异常
'EXCEPTION_HANDLER': 'Book.my_exception.custom_exception_handler'
}
运行结果:
8.接口文档
REST framework可以自动帮助我们生成接口文档。
接口文档以网页的方式呈现。
自动接口文档能生成的是继承自APIView及其子类的视图。
1)安装依赖
REST framewrok生成接口文档需要coreapi库的支持。
pip install coreapi
2)设置接口文档访问路径
在总路由中添加接口文档路径。
文档路由对应的视图配置为rest_framework.documentation.include_docs_urls,
参数title为接口文档网站的标题。
根路由:
urlpatterns = [
...
url(r'^docs/', include_docs_urls(title='我的API文档'))
]
settings.py:
REST_FRAMEWORK = {
# 全局API文档
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}
运行结果:
3)文档描述说明的定义位置
在类视图的文档字符串中,分开方法定义
class BookModelViewSet(ModelViewSet):
'''
list:获取所有数据
create:创建单个对象
'''
运行结果:
如何添加下图中Description???
参数的Description需要在模型类或序列化器类的字段中以help_text选项定义
方法一:
class BookInfo(models.Model):
btitle = models.CharField(max_length=20, verbose_name='名称', help_text='书籍标题')
bpub_date = models.DateField(verbose_name='发布日期', help_text='发布日期')
bread = models.IntegerField(default=0, verbose_name='阅读量', help_text='阅读量')
bcomment = models.IntegerField(default=0, verbose_name='评论量', help_text='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除', help_text='逻辑删除')
方法二:
# 定义书籍模型序列化器
class BookInfoModelSerializer(serializers.ModelSerializer):
class Meta:
model = BookInfo
fields = '__all__'
extra_kwargs = {
'bread': {
#'required': True,
'help_text': '阅读量'
}
}
运行结果: