DRF
序列化定义
什么叫做序列化
- 将程序中的一个数据结构类型转换为其它格式(字典、JSON、XML等)
什么叫做反序列化
- 将其它格式转换为程序中的数据
在开发REST API时,视图中要频繁的进行序列化与反序列化的编写
REST API的视图
在视图中需要做的核心
- 1、将数据库数据序列化为前端所需要的格式,并返回;
- 2、将前端发送的数据反序列化为模型类对象,并保存打数据库中。
虽然每个视图具体的操作不同,但CRUD的实现流程基本套路化,这部分代码是可以复用简化的
CRUD的实现流程
-
增:
- 检验请求数据->执行反序列化过程->保存到数据库->将保存的对象序列化并返回
-
删:
- 判断要删除的数据是否存在->执行数据库删除
-
改:
- 判断要修改的数据是否存在->检验请求的数据->执行反序列化过程->保存数据库->将保存的对象序列化并返回
-
查:
- 查询数据库->将数据序列化并返回
Django REST framework
它是一个用户构建Web API的强大而灵活的工具,通常简称为DRF框架或REST framework
特点:
- 1、提供了定义序列化器Serializer的方法,可以快速根据Django ORM或者其它库自动序列化/反序列化
- 2、提供了丰富的类视图、Mixin扩展类,简化视图的编写
- 3、丰富的定制层级:函数视图、类视图、视图集合到自动生成API,满足各种需要
- 4、多种身份认证和权限认证方式的支持
- 5、内置了限流系统
- 6、直观的API web界面
- 7、可扩展性,插件丰富
DRF的使用
DRF是以Django扩展应用的方式提供的,所以我们可以直接利用已有的Django环境而无需重新创建
安装DRF
- pip install djangorestframework
添加rest_framework应用
- 在settings.py中的INSTALLED_APPS中添加"rest_framework"
序列化
定义方法
-
DRF中的Serializer使用类定义,需要继承自rest_framework.serializers.Serializer
-
定义序列化器的字段与选项‘
- 常用字段1[外链图片转存失败(img-41GliTfd-1564366801227)(assets/99d3c9a5e0987decdf0a750e36a03218c788cbe820b6f9a7a5d5e80a9b73a97f.png)]
- 常用字段2[外链图片转存失败(img-7blNVeKY-1564366801229)(assets/73b09276e0593d68719dee9e866bb2e09b7f12967d4684730252d97fe327e1d8.png)]
- 选项参数
- 通用参数[外链图片转存失败(img-d5lTVQFt-1564366801229)(assets/44d9eb0856a379154fe4ec4b0b03a5ce65af73936b0cecb7e3afcf6b81af4991.png)]
-
serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。
使用
-
定义序列化器
-
创建序列化器对象
-
序列化器和模型类的属性要保持一致
-
构造方法
-
Serializer(instance=None,data=empty,**kwargs)
-
1、用于序列化时,将模型类对象传入instance参数
-
2、用于反序列化时,将要被反序列化的数据传入data参数
-
3、除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据
通过context参数附加的数据,可以通过Serializer对象的context属性获取
-
-
-
基本使用
-
创建要查询的实例化对象
-
构造序列化器对象
如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明
-
获取序列化数据
- 通过序列化器对象.data可以获取序列化后的数据
-
-
关系对象嵌套序列化
-
如果需要序列化的数据中包含有其他关联对象,则对关联对象数据的序列化需要指明。
-
对于关联字段
-
PrimaryKeyRelatedField
- 此字段将被序列化为关联对象的主键。
- 指明字段时需要包含read_only=True或者queryset参数:
- 包含read_only=True参数时,该字段将不能用作反序列化使用
-
StringRelatedField
- 此字段将被序列化为关联对象的字符串表示方式(即__str__方法的返回值)
-
使用关联对象的序列化器
-
-
many参数
- 如果关联的对象数据不是只有一个,而是包含多个数据,需要补充many=True参数
-
反序列化
验证
-
使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象
-
在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False
-
True
- 可以通过序列化器的validated_data属性获取数据
-
False
- 可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字典和字段的错。
- 如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名
-
is_valid()还可以在验证失败时抛出异常serializers.ValidationError,可以通过传递raise_exception=True参数开启,REST framework接收到此异常,会向前端返回HTTP 400 Bad Request响应
-
验证的补充
-
在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是一种验证行为
-
validate_<field_name>
- 对<field_name>字段进行验证
-
validate
- 在序列化器中需要同时对多个字段进行比较验证时,可以定义validate来验证
-
validators
-
在字段中添加validators选项参数,也可以补充验证行为,使用[]包裹验证的函数
- 验证的函数一定要在定义序列化器之前
-
保存
- create()
- update()
- 如果创建序列化器对象的时候没有传递instance实例,则调用save()方法的时候,create()被调用
- 如果传递了instance实例,则调用save()方法的时候,update()被调用
- 在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到
模型类序列化器
和常规的Serializer相同,但有部分扩展:
- 基于模型类自动生成一系列字段
- 基于模型类自动为Serializer生成validators
- 包含默认的create()和update()的实现
定义
-
语法格式
class 序列化器类(serializers.ModelSerializer)
class Meta:
model = 指明参照哪个模型类
fields = 指明为模型类的哪些字段生成 -
可以在shell中查看自动生成的BookInfoSerializer的具体实现
-
指定字段
-
fields
- __all__表名包含所有字段
-
exclude
- 可以明确排除掉哪些字段
-
显示指明字段
- 使用fields = (‘要显示的字段名’)
-
指明只读字段
- read_only_fields,指明只读字段,仅用于序列化输出的字段
-
-
添加额外参数
-
extra_kwargs
class 序列化器类名(serializer.ModelSerializer)
class Meta:
model = 指明模型类
fileds= 指明哪些字段
extra_kwargs = {
“参数”:{},
“参数”:{},
}
-
视图
Request
-
DRF传入视图的request对象不再是Django默认的HttpRequest对象,而是DRF提供的扩展类的Request类的对象
-
DRF提供了Parser解析器,在接收请求后会自动根据Content-Type指明的请求数据类型将请求数据进行parser解析,解析为类字典对象保存到Request对象中
-
Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果
-
常用属性
-
.data
- 返回解析之后的请求体数据
- 包含了解析之后的文件和非文件数据
- 包含了对POST/PUT/PATCH请求方式解析后的数据
- 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
-
.query_params
- 与标准的request.GET()相同,只不过是改了名字
-
Response
-
构造方式
-
Response(data,status=None,template_name=None,headers=None,content_type=None)
-
data
- data数据不要是render处理之后的数据,只需传递python的内建类型即可,DRF会使用render渲染器处理data
- data不能是复杂结构的数据,如Django的模型类对象,对于这样的数据可以使用Serizlizer序列化器序列化处理后再传递给data参数
-
参数说明
-
data
- 为响应准备的序列化处理后的数据
-
status
- 状态码,默认200
-
template_name
- 模板名称,如果使用HTMLRender时需指明
-
headers
- 用于存放响应头信息的字典
-
content_type
- 响应数据的Content-Type,通常此参数无需传递,DRF会根据前端所需类型数据来设置该参数
-
-
-
状态码
-
1xx 信息告知
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS -
2xx 成功
HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
HTTP_207_MULTI_STATUS -
3xx 重定向
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT -
4xx 客户端错误
HTTP_400_BAD_REQUEST
HTTP_401_UNAUTHORIZED
HTTP_402_PAYMENT_REQUIRED
HTTP_403_FORBIDDEN
HTTP_404_NOT_FOUND
HTTP_405_METHOD_NOT_ALLOWED
HTTP_406_NOT_ACCEPTABLE
HTTP_407_PROXY_AUTHENTICATION_REQUIRED
HTTP_408_REQUEST_TIMEOUT
HTTP_409_CONFLICT
HTTP_410_GONE
HTTP_411_LENGTH_REQUIRED
HTTP_412_PRECONDITION_FAILED
HTTP_413_REQUEST_ENTITY_TOO_LARGE
HTTP_414_REQUEST_URI_TOO_LONG
HTTP_415_UNSUPPORTED_MEDIA_TYPE
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
HTTP_417_EXPECTATION_FAILED
HTTP_422_UNPROCESSABLE_ENTITY
HTTP_423_LOCKED
HTTP_424_FAILED_DEPENDENCY
HTTP_428_PRECONDITION_REQUIRED
HTTP_429_TOO_MANY_REQUESTS
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS -
5xx 服务器错误
HTTP_500_INTERNAL_SERVER_ERROR
HTTP_501_NOT_IMPLEMENTED
HTTP_502_BAD_GATEWAY
HTTP_503_SERVICE_UNAVAILABLE
HTTP_504_GATEWAY_TIMEOUT
HTTP_505_HTTP_VERSION_NOT_SUPPORTED
HTTP_507_INSUFFICIENT_STORAGE
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
-
视图说明
-
两个基类
-
APIView
-
定义:APIView是RESTframework提供的所有视图的基类,继承自Django的View父类
-
与View的不同之处
- 传入到视图方法中的是DRF的Request对象,而不是Django的HttpRequest对象
- 视图方法可以返回DRF的Response对象,视图会为响应数据设置(render)符合前端要求的格式
- 任何APIException异常都会被捕获到,并且处理成合适的响应信息
- 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制
-
支持定义的属性
- authentication_classes 列表或元组,身份认证类
- permissoin_classes 列表或元组,权限检查类
- throttle_classes 列表或元组,流量控制类
-
在APIView中仍以常规的类视图定义方法来实现get()、post()或者其他请求方式的方法
-
-
GenericAPIView
rest_framework.generics.GenericAPIView
-
1、继承自APIView,增加了对列表视图和详情视图可能用到的通用支持方法,通常使用时可以搭配一个或多个Mixin扩展类
-
2、支持定义的属性
-
列表视图与详情视图通用
- queryset 列表视图的查询集
- serializer_class 视图使用的序列化器
-
列表视图使用
- pagination_class 分页控制类
- filter_backends 过滤控制后端
-
详情页视图使用
- lookup_field 查询单一数据库对象时使用的条件字段,默认为“pk”
- lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同
-
-
3、提供的方法
-
列表视图与详情视图通用
-
get_queryset(self)
- 返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认 返回queryset属性,可以重写
-
get_serializer_class(self)
- 返回序列化器类,默认返回serializer_class,可以重写
-
get_serializer(self,*args,**kwargs)
- 返回序列化器对象,被其他视图或扩展类使用,如果我们在视图中想要获取序列化器对象,可以直接调用此方法
-
注意,在提供序列化器对象的时候,REST framework会向对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。
-
-
详情视图使用
-
get_object(self)
- 返回详情视图所需的模型类数据对象,默认使用lookup_field参数来过滤queryset。在视图中可以调用该方法获取详情信息的模型类对象
- 如果详情访问的模型类对象不存在,会返回404
- 该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权被访问
-
-
-
4、五个扩展类和子类视图
-
ListModelMixin
源代码:
class ListModelMixin(object):
“”"
List a queryset.
“”"
def list(self, request, *args, **kwargs):
# 过滤
queryset = self.filter_queryset(self.get_queryset())
# 分页
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
# 序列化
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)- 列表视图扩展类,提供list(request,*args,**kwargs)方法快速实现列表视图,返回200状态码
- list方法会对数据进行过滤和分页
-
CreateModelMixin
class CreateModelMixin(object):
“”"
Create a model instance.
“”"
def create(self, request, *args, **kwargs):
# 获取序列化器
serializer = self.get_serializer(data=request.data)
# 验证
serializer.is_valid(raise_exception=True)
# 保存
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)def perform_create(self, serializer): serializer.save() def get_success_headers(self, data): try: return {'Location': str(data[api_settings.URL_FIELD_NAME])} except (TypeError, KeyError): return {}
- 创建视图扩展类,提供create(request,*args,**kwargs)方法快速实现创建资源的视图,成功返回201状态码
- 如果序列化器对前端发送的数据验证失败,返回400错误
-
RetrieveModelMixin
class RetrieveModelMixin(object):
“”"
Retrieve a model instance.
“”"
def retrieve(self, request, *args, **kwargs):
# 获取对象,会检查对象的权限
instance = self.get_object()
# 序列化
serializer = self.get_serializer(instance)
return Response(serializer.data)- 详情视图扩展类,提供retrieve(request,*args,**kwargs)方法,可以快速实现返回一个存在的数据对象。
- 如果存在,返回200,否则返回404
-
UpdateModelMixin
class UpdateModelMixin(object):
“”"
Update a model instance.
“”"
def update(self, request, *args, **kwargs):
partial = kwargs.pop(‘partial’, False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)if getattr(instance, '_prefetched_objects_cache', None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} return Response(serializer.data) def perform_update(self, serializer): serializer.save() def partial_update(self, request, *args, **kwargs): kwargs['partial'] = True return self.update(request, *args, **kwargs)
- 更新视图扩展类,提供update(request,*args,**kwargs)方法,可以快速实现更新一个存在的数据对象,也提供partial_update(request,*args,**kwargs)方法,可以实现局部刷新
- 成功返回200,失败返回400
-
DestroyModelMixin
class DestroyModelMixin(object):
“”"
Destroy a model instance.
“”"
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)def perform_destroy(self, instance): instance.delete()
- 删除视图扩展类,提供destroy(request,*args,**kwargs)方法,可以快速实现删除一个存在的数据对象
- 成功返回204,不存在返回404
-
子类视图
-
ListAPIView
- get
-
CreateAPIView
- post
-
RetireveAPIView
- get
-
UpdateAPIView
- put
- patch
-
DestroyAPIView
- delete
-
集成的子类视图
-
RetireveUpdateAPIView
- get
- put
- patch
-
RetrieveUpdateDestoryAPIView
- get
- put
- patch
- delete
-
-
-
-
-
视图集ViewSet
-
使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:
-
list()
- 提供一组数据
-
retrieve()
- 提供单个数据
-
create()
- 创建数据
-
update()
- 更新数据
-
destory()
- 删除数据
-
-
ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等
-
视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上
-
action
- 在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个。
-
常用是视图集父类
-
ViewSet
- 继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
-
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法
- GenericViewSet
- 继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发。
- ModelViewSet
- 继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
- ReadOnlyModelViewSet
- 继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin。
-
视图集中定义添加action动作
-
添加自定义动作需要使用rest_framework.decorators.action装饰器
-
action装饰器
-
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同
-
methods
- 该action支持的请求方式,以列表的形式传递
-
detail
-
表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
-
True
- 表示使用通过URL获取的主键对应的数据对象
-
False
- 表示不使用URL获取主键
-
-
URL的定义
- 需要在as_view()中传入以字典的形式的参数,请求方式为键,action为值
-
-
-
路由 Routers
-
对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。
-
SimpleRouter
-
DefaultRouter
-
使用方法
-
1、创建router对象,并注册视图集
from rest_framework import routers
注册视图集
router = router.SimpleRouter()
router.register(r’路由规则’,要注册的视图集,路由名称的前缀) -
对上参数说明
-
register(prefix, viewset, base_name)
-
prefix
- 该视图集的路由前缀
-
viewset
- 要注册的视图集
-
base_name
- 路由名称的前缀
-
-
2、添加路由数据
- urlpatterns = [
…
]
urlpatterns += router.urls - urlpatterns = [
…
url(r’^’, include(router.urls))
]
- urlpatterns = [
-
-
视图集中包含附加action的
-
代码:
class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer@action(methods=['get'], detail=False) def latest(self, request): ... @action(methods=['put'], detail=True) def read(self, request, pk): ...
-
最终会形成的路由
^books/latest/$ name: book-latest
^books/{pk}/read/$ name: book-read
-
-
-
路由router形成URL的方式
- SImpleRouter[外链图片转存失败(img-d2qh0Qkx-1564366801230)(assets/187f7953da688214af6f0afd9bac1260b569a62c9e926cb16bdbe038b8db4bef.png)]
- DefaulfRouter[外链图片转存失败(img-inMj6IWO-1564366801230)(assets/13819fa2722e1627faae5486e8a43076eced699da709d5a155bd49fdbd40c80c.png)]
其它功能
认证 Authentication
-
1、可以在配置文件中配置全局默认的认证方案
REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: (
‘rest_framework.authentication.BasicAuthentication’, # 基本认证
‘rest_framework.authentication.SessionAuthentication’, # session认证
)
} -
2、也可以通过在每个视图中通过设置authentication_classess属性来设置
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.views import APIViewclass ExampleView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
… -
认证失败会有两种可能的返回值
- 401 Unauthorized 未认证
- 403 Permission Denied 权限被禁止
权限Permissions
-
权限控制可以限制用户对于视图的访问和对于具体数据对象的访问
- 在执行视图的dispatch()方法前,会先进行视图访问权限的判断
- 在通过get_object()获取具体对象时,会进行对象访问权限的判断
-
使用
-
①可以在配置文件中设置默认的权限管理类
REST_FRAMEWORK = {
‘DEFAULT_PERMISSION_CLASSES’: (
‘rest_framework.permissions.IsAuthenticated’,
)
} -
②如果未指明,采用这个配置
‘DEFAULT_PERMISSION_CLASSES’: (
‘rest_framework.permissions.AllowAny’,
) -
③可以在具体的视图中通过permission_classes属性来设置
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIViewclass ExampleView(APIView):
permission_classes = (IsAuthenticated,)
…
-
-
提供的权限
- AllowAny 允许所有用户
- IsAuthenticated 仅通过认证的用户
- IsAdminUser 仅管理员用户
- IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取
限流Throttling
-
可以对接口访问的频次进行限制,来减轻服务器压力
-
使用
-
全局配置
REST_FRAMEWORK = {
‘DEFAULT_THROTTLE_CLASSES’: (
‘rest_framework.throttling.AnonRateThrottle’,
‘rest_framework.throttling.UserRateThrottle’
),
‘DEFAULT_THROTTLE_RATES’: {
‘anon’: ‘100/day’,
‘user’: ‘1000/day’
}
}- 在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全局配置,
- DEFAULT_THROTTLE_RATES可以使用 second,minute,hour或day来指明周期
-
局部使用
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIViewclass ExampleView(APIView):
throttle_classes = (UserRateThrottle,)
…- 在具体视图中通过throttle_classes属性配置
-
可选限流类
-
AnonRateThrottle
- 限制所有匿名未认证用户,使用IP区分用户
- 使用DEFAULT_THROTTLE_RATES[‘anon’] 来设置频次
-
UserRateThrottle
- 限制认证用户,使用User id 来区分
- 使用DEFAULT_THROTTLE_RATES[‘user’]来设置频次
-
ScopedRateThrottle
- 限制用户对于每个视图的访问频次,使用ip或user id
-
-
过滤Filtering
-
对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。
-
使用
-
下载django-filter
- pip install django-filter
-
在配置文件中增加过滤后端的设置
INSTALLED_APPS = [
…
‘django_filters’, # 需要注册应用,
]REST_FRAMEWORK = {
‘DEFAULT_FILTER_BACKENDS’: (‘django_filters.rest_framework.DjangoFilterBackend’,)
} -
在视图中添加filter_fields属性,指定可以过滤的字段
class BookListView(ListAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
filter_fields = (‘btitle’, ‘bread’)
-
排序
-
对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。
-
使用
class BookListView(ListAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
filter_backends = [OrderingFilter]
ordering_fields = (‘id’, ‘bread’, ‘bpub_date’)-
在类视图设置filter_backends
-
使用rest_framework.filters.OrderingFilter过滤器
-
REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,
- 如果包含了ordering参数,就按照ordering参数指明的排序字段对数据集进行排序
-
前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明
-
分页 Pagination
-
全局分页
REST_FRAMEWORK = {
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 100 # 每页数目
}- 可以在配置文件中设置全局的分页方式
-
局部分页
class LargeResultsSetPagination(PageNumberPagination):
page_size = 1000
page_size_query_param = ‘page_size’
max_page_size = 10000-
可以通过自定义Pagination类,来为视图添加不同分页行为,在视图中通过pagination_class属性来指明
class BookDetailView(RetrieveAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
pagination_class = LargeResultsSetPagination -
如果在视图内关闭分页功能,只需在视图内设置
- pagination_class=None
-
-
可选分页器
-
PageNumberPagination
-
前端访问网址形式
-
可以在子类中定义的属性
-
page_size
- 每页数目
-
page_query_param
- 前端发送的页数关键字名,默认为“page”
-
page_size_query_param
- 前端发送的每页数目关键字名,默认为None
-
max_page_size
- 前端最多能设置的每页数量
-
-
-
LimitOffsetPagination
-
前端访问网址形式
-
可以在子类中定义的属性
-
default_limit
- 默认限制,默认值与PAGE_SIZE设置一致
-
limit_query_param
- limit参数名,默认为limit
-
offset_query_param
- offset参数名,默认为offset
-
max_limit
- 最大limit限制,默认为None
-
-
-
异常处理
-
DRF提供了异常处理,可以自定义异常处理函数
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
# 先调用REST framework默认的异常处理方法获得标准错误响应对象
response = exception_handler(exc, context)# 在此处补充自定义的异常处理 if response is not None: response.data['status_code'] = response.status_code return response
-
使用
-
在配置文件中声明自定义的异常处理
REST_FRAMEWORK = {
‘EXCEPTION_HANDLER’: ‘my_project.my_app.utils.custom_exception_handler’
} -
如果未声明,会采用默认的方式
REST_FRAMEWORK = {
‘EXCEPTION_HANDLER’: ‘rest_framework.views.exception_handler’
}
-
-
REST framework定义的异常
-
APIException
- 所有异常的父类
-
ParseError
- 解析错误
-
AuthenticationFailed
- 认证错误
-
NotAuthenticated
- 尚未认证
-
PermissionDenied
- 权限拒绝
-
NotFound
- 未找到
-
MethodNotAllowed
- 请求方式不支持
-
NotAcceptable
- 要获取的数据格式不支持
-
Throttled
- 超过限流次数
-
ValidationError
- 检验失败
-
自动生成接口文档
-
1、安装依赖
- REST framework生成接口文档需要coreapi库的支持
- pip install coreapi
-
2、设置接口文档访问路径
-
在总路由中添加接口文档路径
-
文档路由对应的视图配置为rest_framework.documentation
-
路径
- from rest_framework.documentation import include_docs_urls
-
urlpatterns = [
…
url(r’^路由匹配’, include_docs_urls(接口文档网站的标题=‘My API title’))
]
-
3、文档描述说明的定义位置
-
①单一方法的视图,可直接使用诶视图的文档字符串
class BookListView(generics.ListAPIView):
“”"
返回所有图书信息.
“”" -
②包含多个方法的视图,在类视图的文档字符串中,分开方法定义
class BookListCreateView(generics.ListCreateAPIView):
“”"
get:
返回所有图书信息.post: 新建图书. """
-
③对于视图集ViewSet,仍在类视图的文档字符串中分开定义,但是应使用action名称区分
-
-
4、访问接口文档网页
- ① 视图集ViewSet中的retrieve名称,在接口文档网站中叫做read
- ②参数的Description需要在模型类或序列化器类的字段中以help_text选项定义
XMind: ZEN - Trial Version