Serializer & ModelSerializer

初級Serilaizer和ModelSerializer:

Serializer

作用:
可通過DRF的Serializer,來將數(shù)據(jù)保存到數(shù)據(jù)庫中。
我們甚至都可以不用模型去保存了。
也就是與Form功能很像。

Serializer這里的功能可以相當于django的 form功能,也可以完成序列化為json的功能。

實例:

# serializers.py

from rest_framework import serializers
from ..models import Goods


class GoodsSerializer(Serializer):
    name = serializers.CharField(required=True, max_length=100)
    click_num = serializers.IntegerField(default=0)

# views.py

from rest_framework.views import APIView
from rest_framework.response import Response  # 這個是DRF的Response
from .serializers import GoodsSerializer

class GoodsListAPIView(APIView):
    def get(self, request, format=None):
        goods = Goods.objects.all()[:10]
        goods_sl = GoodsSerializer(goods, many=True) # 序列化為數(shù)組 注意多個
        return Response(goods_sl.data)  # goods_sl.data就是序列化之后的數(shù)據(jù),
        # 這里也沒有添加其他的狀態(tài)

圖片.png

比如DRF 的 serializer,可以自動完善ImageField的路徑。

validated_data

可以重寫Serializer中的create方法:

圖片.png

注意參數(shù)validated_data,這里會把name,click_num,goods_front這些seriliazer字段放入validated_data字典中。

如果這個序列類作為前端添加的接口的話,那么這可以:
1)通過Serializer去驗證前端json傳遞過來的body。
request.data # 就是DRF的request.data
2)保存數(shù)據(jù)到數(shù)據(jù)庫中。

ModelSerializer
更加方便。自己會去映射。這樣寫起來更加簡單。

class GoodsSerializer(Serializer):
    class Meta:
        model = Goods
        fields = "__all__"

Serializer嵌套Serializer

圖片.png

** DRF status**

HTTP_200_OK 一般是GET請求的一個響應。
HTTP_201_CREATED 一般是POST請求的一個響應。

** 設置分頁 **

系統(tǒng)設置分頁.png

也可以單獨設置分頁。


圖片.png

注意:count是總共的個數(shù)。


官方鏈接:
http://www.django-rest-framework.org/api-guide/serializers/

ModelSerializer 比Serializer封裝好了一層,直接自己生成的create和update,不用覆蓋了,其實推薦用這個,畢竟Serializer封裝的很低級,既然用django,就要用好點的。

Serializer本身就是一種字段。

翻譯:
Serializers允許復雜的數(shù)據(jù),例如:querysets和model實例轉(zhuǎn)為能被輕易渲染進入JSON,XML或者其他內(nèi)容形式的天然的Python數(shù)據(jù)類型。Serializers也體用了反序列化deserialization。
Serializers在REST framework中工作起來很像Django的Form和ModelForm類。
restful framework提供的Serializer類給我們了強大的,通用的方式去控制responses,以及ModelSerializer類提供了更加好的方式去應付model實例和querysets。

定義Serializers
讓我們從創(chuàng)建一個簡單的python對象開始:

from datetime import datetime

class Comment(object):
    def __init__(self, email, content, created=None):
        self.email = email
        self.content = content
        self.created = created or datetime.now()

comment = Comment(email='leila@example.com', content='foo bar')

我們將會聲明一個serializer,我們可以使用它去序列化和反序列化Comment對象。
聲明一個serializer看起來很類似于聲明一個form:

from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

序列化對象

我們現(xiàn)在可以使用CommentSerializer去序列化一個comment,或者列表化很多comments。
還是一樣,使用Serializer很像使用一個Form類:

serializer = CommentSerializer(comment)
serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}

注意:data是一個字典。

此時,我們已經(jīng)將model實例轉(zhuǎn)換為了python天然的數(shù)據(jù)類型。我們將data寫入到json中結(jié)束實例化步驟(上面都是在python shell中做的,沒有寫>>>注意下):

>>> from rest_framework.renderers import JSONRenderer
>>> json = JSONRenderer().render(serializer.data)
>>> json
'{"email":"leila@example.com","content":"foo bar","created":"2017-10-31T18:07:45.939182"}'

反序列化對象

反序列化也是類似的,首先我們應該解析流到python的天然的數(shù)據(jù)類型中:

from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser

stream = BytesIO(json)
data = JSONParser().parse(stream)
data
# {u'content': u'foo bar', u'email': u'leila@example.com', u'created': u'2017-10-31T18:07:45.939182'}

serializer = CommentSerializer(data=data)  # 這個原來是反序列化
serializer.is_valid()
# True
serializer.validated_data

保存instances

如果我們想能夠返回完整的基于合法數(shù)據(jù)的對象,我們需要實現(xiàn)create()update()方法,例如:

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

    def create(self, validated_data):
        return Comment(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        return instance

如果你的對象對應的是Django的models,那么你也想確保這些方法將會保存到數(shù)據(jù)庫中。比如,如果Comment是一個Django模型,那么這些方法將會是這樣:

def create(self, validated_data):
        return Comment.objects.create(**validated_data)

def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        instance.save()
        return instance

現(xiàn)在當反序列化數(shù)據(jù)的時候,我們需要調(diào)用save()去返回一個對象實例:

comment = serializer.save()

調(diào)用save()將會創(chuàng)建一個新的實例,或者更新一個已經(jīng)存在的實例:

# .save() will create a new instance.
serializer = CommentSerializer(data=data)

# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)

create()update()方法都是可選的,你可以實現(xiàn)一種也可以都實現(xiàn),或者都不識閑,取決于你的serializer的類的使用情況。

傳遞額外的屬性到save()方法中:
有的時候你想你的view代碼能夠注入額外的數(shù)據(jù)當在保存實例的時候。這些額外的數(shù)據(jù)可能包含的信息比如:當前的user,當前的時間,或者其他的非request數(shù)據(jù)。

你也可以像下面這樣去調(diào)用save()方法:

serializer.save(owner=request.user)

任何的額外的關鍵字參數(shù)將會被包含進validated_data參數(shù)中當create()或者update()被調(diào)用的時候。

直接覆蓋save()方法:

有的時候,create()update()方法的名字可能是有含義的,比如,在一個contact form中,我們可能不是創(chuàng)建新的實例,而是發(fā)送郵件或者其他的信息。
在這樣的情況下你可能不會選擇直接去覆蓋save()方法,

太多了

http://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容