序列化器:
作用:
1.序列化:把模型类对象转化成字典,经过response之后变成json字符串
2.反序列化:把字典转化成模型类对象(客户端发送过来的数据,经过request之后变成字典)
3.完成数据校验功能(反序列化)
序列化:
定义好Serializer类后,就可以创建Serializer对象
Serializer(instance=None, data=empty, **kwarg)
1.用于序列化的时候,将模型类对象传入instance参数(xxx.data获取序列化后的字典)
2.用于反序列化时,将要被反序列化的数据传入data参数
3.除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如 serializer = AccountSerializer(account, context={'request': request}) 通过context参数附加的数据,可以通过Serializer对象的context属性获取
4.如果序列化的不是单个模型类对象,而是查询集QuerySet,则使用many=True说明,例 serializer = StudentSerializer(instance=student_list,many=True)
反序列化:
(xxx代表序实例化的列化器对象)
1.在获取反序列化的数据之前,必须调用is_valid()方法进行验证,成功返回True,失败False(通过xxx.errors获取错误信息)(还可以在失败时抛出异常,传递raise_exception=True参数开启,例 xxx.is_valid(raise_exception=True )
2.验证成功,使用xxx.validated_data属性获取数据
3.定义序列化器时,指明每个字段的序列号类型和选项参数,本身就是一种验证行为,还有三种验证方法
验证方法:
验证完成以后务必要返回传入的数据,失败 raise serializers.ValidationError("原因")
1.def validate_<字段名>(用户提交的字段数据):
2.def validate(实例化序列化器类时的data参数):
3.在序列化类外面定义方法,在字段里直接使用 validators=[定义的方法]
序列化器实现了create跟update方法,如果创建序列化器对象的时候,没有传递instance实例,则调用save()方法的时候,create()被调用,相反,如果传递了instance实例,则调用save()方法的时候,update()被调用。
说明:
1.在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到 serializer.save(owner=request.user)
2.默认序列化器必须传递所有required的字段,否则会抛出验证异常。但是我们可以使用partial参数来允许部分字段更新 serializer = StudentSerializer(instance=instance, data=data, partial=True)
模型类序列化器
ModelSerializer与常规的Serializer相同,但提供了:
1.基于模型类自动生成一系列字段
2.基于模型类自动为Serializer生成validators,比如unique_together
3.包含默认的create()和update()的实现
from rest_framework import serializers
from students.models import Student
class StudentModelSerializer(serializers.ModelSerializer):
# 如果模型类序列化器,必须声明本次调用是哪个模型,模型里面的哪些字段
class Meta:
model = Student
fields = ["id","name","age","description","sex"]
# fields = "__all__" # 表示操作模型中的所有字段
exclude = ['sex']
# 使用exclude可以明确排除掉哪些字段
read_only_fields = ('id')
# 可以通过read_only_fields指明只读字段,即仅用于序列化输出的字段
# 添加额外的验证选项
extra_kwargs = {
"sex":{"write_only":True,},
"id":{"read_only":True,}
}
视图
请求与响应
request:REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSON、表单等)将请求数据进行parse解析,解析为类字典[QueryDict]对象保存到Request对象中。
常用属性:
1.request.data返回解析之后的请求体数据,类似django中标准的request.POST
特性:
1.包含了解析之后的文件和非文件数据
2.包含了对POST、PUT、PATCH请求方式解析后的数据
3.利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
2.request.query_params
与Django标准的request.GET
相同,只是更换了更正确的名称而已
response:REST framework提供了一个响应类Response
,使用该类构造响应对象时,响应的具体数据内容会被转换(render渲染)成符合前端需求的类型。
REST framework提供了Renderer
渲染器,用来根据请求头中的Accept
(接收数据类型声明)来自动转换响应数据到对应格式。
两个基类视图
APIView:传入的是改动后的request
GenericAPIView:继承自APIVIew
,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持。通常在使用时,可搭配一个或多个Mixin扩展类。
属性:
Serializer_class:指明视图使用的序列化器
queryset: 指明使用的数据查询集
方法:
1.get_serializer_class(self),返回序列化器类,默认返回serializer_class
,可以重写(多个序列化器的时候)
2.get_serializer(self,args,*kwargs),返回序列化器对象
1.get_queryset(self),返回视图使用的查询集,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回queryset
属性,可以重写
2.get_object(self),返回详情视图所需的模型类数据对象,主要用来提供给Mixin扩展类使用。
五个视图扩展类
作用:
提供了几种后端视图(对数据资源进行曾删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通过继承相应的扩展类来复用代码,减少自己编写的代码量。
这五个扩展类需要搭配GenericAPIView父类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法。
使用:定义好get、post等方法,将视图扩展类提供的函数作为返回值
ListModelMixin
列表视图扩展类,提供list(request, *args, **kwargs)
方法快速实现列表视图,返回200状态码。
使用:
from rest_framework.mixins import ListModelMixin
class BookListView(ListModelMixin, GenericAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def get(self, request):
return self.list(request)
CreateModelMixin
提供create(request, *args, **kwargs)
方法快速实现创建资源的视图,成功返回201状态码。
如果序列化器对前端发送的数据验证失败,返回400错误。
RetrieveModelMixin
提供retrieve(request, *args, **kwargs)
方法,可以快速实现返回一个存在的数据对象。
如果存在,返回200, 否则返回404。
UpdateModelMixin
提供update(request, *args, **kwargs)
方法,可以快速实现更新一个存在的数据对象。
成功返回200,序列化器校验数据失败时,返回400错误。
同时也提供partial_update(request, *args, **kwargs)
方法,可以实现局部更新。
DestroyModelMixin
提供destroy(request, *args, **kwargs)
方法,可以快速实现删除一个存在的数据对象。
成功返回204,不存在返回404。
GenericAPIView的视图子类
1)CreateAPIView
提供 post 方法
继承自: GenericAPIView、CreateModelMixin
2)ListAPIView
提供 get 方法
继承自:GenericAPIView、ListModelMixin
3)RetrieveAPIView
提供 get 方法
继承自: GenericAPIView、RetrieveModelMixin
4)DestoryAPIView
提供 delete 方法
继承自:GenericAPIView、DestoryModelMixin
5)UpdateAPIView
提供 put 和 patch 方法
继承自:GenericAPIView、UpdateModelMixin
6)RetrieveUpdateAPIView
提供 get、put、patch方法
继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin
7)RetrieveUpdateDestoryAPIView
提供 get、put、patch、delete方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin
视图集
ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。
视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。如:
class BookInfoViewSet(viewsets.ViewSet):
def list(self, request):
books = BookInfo.objects.all()
serializer = BookInfoSerializer(books, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
try:
books = BookInfo.objects.get(id=pk)
except BookInfo.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = BookInfoSerializer(books)
return Response(serializer.data)
在设置路由时,我们可以如下操作
urlpatterns = [
url(r'^books/$', BookInfoViewSet.as_view({'get':'list'}),
url(r'^books/(?P<pk>\d+)/$', BookInfoViewSet.as_view({'get': 'retrieve'})
]
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。