初級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)

比如DRF 的 serializer,可以自動完善ImageField的路徑。
validated_data
可以重寫Serializer中的create方法:

注意參數(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

** DRF status**
HTTP_200_OK 一般是GET請求的一個響應。
HTTP_201_CREATED 一般是POST請求的一個響應。
** 設置分頁 **

也可以單獨設置分頁。

注意: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