restframework框架源码初识(2)

                     之前我们已经了解了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<pk>\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里面还有很多功能,后面我们可以慢慢看源码来进行挖掘出来。

 

posted @ 2018-08-01 20:33  鲁之敬  阅读(104)  评论(0编辑  收藏  举报