之前我们已经了解了restframework的处理请求的大概流程,也大概讲了restframework的APIView组件,现在我们再来讲讲它的另外一个
很牛逼的组件,序列化组件。
在讲这序列化组件之前我们先要了解另外一个知识点,RESTfull规范。
一,什么是RESTfull规范:
RESTfull与技术无关,它代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移,它的理念就是一切皆资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性,对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)。
浏览器的任何请求都是对资源的操作,大致就是增,删,改,查,这种风格的url请求里不会有动词(dange,add,list....),例如:
books books book/add/ addbook book/1/change changebook book/1/delete changebook
它一般把url做成下面这种:
get 查看 books ------------> post 添加 get 查看 book/1/------------- delete 删除 put 更新
它根据你不同的请求方式来做相对应的操作:
GET :从服务器取出资源(一项或多项)
POST :在服务器新建一个资源
PUT :在服务器更新资源(客户端提供改变后的完整资源)
PATCH :在服务器更新资源(客户端提供改变的属性)
DELETE :从服务器删除资源
在view视图文件里处理:
class BookDetailViewSet(APIView): def get(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj) return Response(bs.data) def put(self,request,pk): book_obj=Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,data=request.data) if bs.is_valid(): bs.save() return Response(bs.data) else: return HttpResponse(bs.errors)
因为像改,删操作需要相应的参数,所以在url文件里设计url也要区分开:
url(r'^books/$', views.BookView.as_view()), #发送查看,创建请求路由 url(r'^books/(?P\d+)/$ ', views.BookDataView.as_view()), #发送更改,删除请求
所以RESTfull只是一种架构风格,并没有实际的强制性,你可以根据自己的喜好选择架构风格,但是我还是比较推荐这种风格,它的优点是数据操作的解耦和,一种
请求对应一种操作,对于以后的扩展性有很好的友好性。
接下来我们步入正题
二,restframework的序列化组件:
在Djiango中有自带的序列化工具,它的可以根据你指定的数据结构去序列化,使用起来很方便:
from django.core.serializers import serialize #序列化的方法 #第一种 class Get_ret(View): def get(self,request): ret=models.Book.objects.all() ret=serialize('json',ret) return HttpResponse(ret) def post(self,request): pass
这里我们要讲的是restframework的序列化组件:
from rest_framework import serializers
class BookSerializers(serializers.Serializer):
title=serializers.CharField() #序列化
price=serializers.CharField()
publishDate=serializers.DateField()
# 针对一对多
publish=serializers.CharField(source="publish.name")
publish_email=serializers.CharField(source="publish.email")
# 针对多对多
authors=serializers.SerializerMethodField()
这个序列化组件更加强大,它内部封装了很多方法,它可以序列化你指定的字段,查看它的源码你可以看见它可以支持很多类型的字段:
restframework的serializers组件还有一个更强大的接口,serializers.ModelSerializer接口,它的功能包含了Djiango的Model.Form跟 restframework的serializers序列化
功能,也就是它既可以对前端数据做校验也可以做序列化与反序列化。看它的源码就可以大致看出来它具备的功能:
从源码可以看出它继承了serializer,也就是有序列化的功能,另外它还有类似create(),updata()方法,也就是增跟改功能,实现功能如下:
在view视图文件里如下:
from app01.models import * from app01.serializes import BookSerialize from rest_framework.response import Response class BookView(APIView): def get(self,request): #查看所有数据请求 book_list = Book.objects.all() #得到所有数据 bs = BookSerialize(book_list,many=True) #调用rest_framework的序列化功能将数据序列化josn格式 return Response(bs.data) #将数据返回 def post(self,request): #创建数据请求 print(request.data) bs = BookSerialize(data=request.data) #将前端发送的数据反序列化 if bs.is_valid(): #serializers.ModelSerializer它既可以序列化数据,也可以对数据做验证 bs.save() #调用数据库创建功能 return Response(bs.data) #将新数据返回给前端 else: return Response(bs.errors) class BookDataView(APIView): def get(self,request,pk): #查看某条数据请求 book_obj = Book.objects.filter(pk=pk).first() bs = BookSerialize(book_obj,many=False) #many参数为False是查看单条数据 return Response(bs.data) def put(self,request,pk): #更改某条数据请求 book_obj = Book.objects.filter(pk=pk).first() bs = BookSerialize(data=request.data,instance=book_obj) if bs.is_valid(): bs.save() return Response(bs.data) def delete(self,request,pk): #删除某条数据请求 Book.objects.filter(pk=pk).delete() return Response('OK')
新建一个专门处理序列化数据的文件:
from rest_framework import serializers from app01.models import * class BookSerialize(serializers.ModelSerializer): class Meta: model = Book #序列化的具体表 fields = '__all__' #序列化字段,__all__为所有字段 class PublishSerialize(serializers.ModelSerializer): class Meta: model = Publish fields = '__all__'
经过序列化处理的数据都.data里,它的结构是列表里套了一个字典,它内部实现的原理大概如下:
book_list=Book.objects.all() bs=BookSerializers(book_list,many=True) # 序列化数据 return Response(ps.data) 解析: data=[] for obj in publish_list: data.append({ "name":obj.name, "city":obj.city, "email":obj.email, "publish":obj.publish.email, # if 字段是多对多字段: "authors":get_authors(obj) }) self.data=data
对于对大多数的数据需要序列化的时候可以使用serializers.ModelSerializer方法,比较简单方便,而对于只需要对指定字段进行序列化需求可以使用serializers方法。
当然ModelSerializer里面还有很多功能,后面我们可以慢慢看源码来进行挖掘出来。