django序列化與反序列化
from rest_framwork import serializers
serializers.ModelSerializer
模型類序列化器,必須依據模型類建立序列化器
- 基於模型類自動生成一系列字段
包含默認的 crate()和update()前端
定義ModelSerializer類
定義序列化器
- class BookInfoSerializer(serializer.ModelSerializer):
class Meta:
model = BookInfo
filels = 'all'
read_only_fields = ('id', 'readcount', 'commentcount')
extra_kwargs = {
'readcount': {'min_value': 0, 'required': True},
'commentcount': {'max_value': 0, 'required': True},
}
- model,指明參照的那個模型類
- fields ,指明爲模型類的那些字段生成
- fields = ‘all’表示全部字段
- exclude = ('iamge',) 表示排除哪些字段
- fields = ('id','name','readcount') 表示顯示哪些字段
- read_only_fields指明只讀字段,即僅用於序列化輸出的字段
- extra_kwargs,爲ModelSerializer添加或修改原有的選型參數
extra_kwargs = {
'readcount': {'min_value': 0, 'required': True},
'commentcount': {'max_value': 0, 'required': True},
}數據庫
serailizers.Serializer
便可覺得數據庫模型類定義,也能夠爲非數據庫模型類的數據定義
定義Serializer類
定義序列化器
- class BookInfoSerializer(serializers.Serializers)
id = serializers.IntegerField(label='ID', read_only=True)
字段和選選項django
建立Serializer對象
- s = BookInfoSerializer(instance=None, data=empty, **kwarg)
- 將程序中的數據結構類型轉換爲其餘類型(字典,JSON,XML)Django中將模型類轉化爲JSON
- 基本使用
- 獲取須要序列化的對象
- from book.models import BookInfo
book = BookInfo.objects.get(id=4)
- books = BookInfo.objects.all()
- 構造序列化器對象
- from book.serializers import BookInfoSerializer
serializer = BookInfoSerializer(instance=book)
- serializer = BookInfoSerializer(instace=books, many=True)
- 獲取序列化數據
- 關聯對象嵌套序列化
- 若是須要序列化的數據中包含有其餘關聯對象,則對關聯對象數據的序列化須要指明
- 關聯的對象數據是一個
- PrimaryKeyRelatedFiled
- class PeopleInfoSerializer(serializers.Serializer):
#book = serializers.PrimaryKeyRelatedFiled(label='圖書',read_only=True)
book = serializers.PrimaryKeyRelatedFiled(label='圖書',queryset=BookInfo.objects.all())
- 包含read_only=True時,該字段不能用於反序列化使用
- 包含queryset參數時,將被用做反序列化時參數校驗使用
- 使用序列化器對象的data方法時
對應字段顯示的是本表數據
- {'id': 10, 'book': 3, 'description': '獨孤九劍', 'gender': 1, 'name': '令狐沖'}
- StringRelatedFiledd
- 此字段被序列化爲關聯對象的字符串表示方式(即__str__方法的返回值)
- book = serializers.StringRelatedFiled(label='圖書')
- class BookInfoSerializer(serializers.serializer):
...
def str(self):
return self.name
- 使用序列化器對象的data方法時
對應字段顯示的關聯表__str__方法返回的數據
- {'description': '獨孤九劍', 'name': '令狐沖', 'gender': 1, 'book': '笑傲江湖', 'id': 10}
- 使用關聯對象的序列化器
- book = BookInfoSerializer()
- 使用序列化器對象的data方法時
對應字段顯示的式OrderDict對象=有序字典
- {'book': OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 28), ('commentcount', ('image', None)]), 'gender': 1, 'name': '令狐沖', 'description': '獨孤九劍', 'id': 10}
- 關聯對象的數據是多個
- many參數
- 使用django建立模型類的時候,一對多的一表有peopleinfo_set隱藏字段
- 若是關聯對象的數據不是隻有一個,而是包含多個數據,如想序列化對應數據時,此時關聯字段類型的指明仍使用上述方法,只是在聲明關聯字段時,多補充一個many=True參數便可
- class BookInfoSerializer(serializers.Serializer):
peopleinfo_set = serializers.PrimarykeyRelatedField(read_only=True,many=True)
-
from book.models import BookInfo
from book.serializers import BookInfoSerializer
book = BookInfo.objects.get(id=3)
serializer = BookInfoSerializer(book)
serializer.data
{'id': 3, 'peopleinfo_set': [10, 11, 12, 13], 'commentcount': 18, 'name': '笑傲江湖', 'readcount': 28, 'pub_date': '199-24', 'image': None}ui
反序列化
- 與序列化相反,Django中將JSOn字符串轉化爲Django中的模型類對象
- 驗證數據
-
from book.serializers import BookInfoSerializer
data = {'pub_date':123}
serializer = BookInfoSerializer(data=data)
serializer.is_valid()
False
serializer.errors
{'pub_date': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]].', code='invalid')], 'name': [ErrorDetail(string='This field is required.', code='required')]}
serializer.validated_data
{}rest
- 使用序列化器進行反序列化時,須要對數據進行驗證後,才能獲取
驗證成功的數據或保存成模型類對象
- 序列化器對象調用is_valid()
- 經過字段類型和選型驗證,驗證成功返回True,失敗返回False
- is_valid(raise_exception=True)
- 驗證失敗後拋出serializers.ValidationError
- 向前端返回HTTP 400 Bad Request響應
- 自定義驗證方法
- validate_
- 在序列化器中定義固定方法,驗證單一字段
- class BookInfoSerializer(serializers.Serializer):
"""圖書數據序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增
def validate_readcount(self,value):
if value < 0:
raise serializers.ValidationError('閱讀數量不能爲負數')
return value
- validate
- 在序列化器中定義固定方法,驗證多個字段
- class BookInfoSerializer(serializers.Serializer):
id = serializers.IntegerFiled(label='ID',read_only=True)
readcount = serializers..IntegerFiled(label='閱讀量',required=False)
commentcount = serializers..IntegerFiled(label='評論量',required=False)
def validate(self,attrs):
readcount = attrs.get('readcount')
commentcount = attrs['commentcount']
if commentcount > readcount:
raise serializers.ValidationError('評論量不能大於閱讀量')
returen attrs
- validators
- 在字段中添加validators選項參數,補充驗證行爲
- class BookInfoSerializer(serializers.Serializer):
def custom_validate(value):
raise serializers.ValidationError('我就是來搗亂的')code
"""圖書數據序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
name = serializers.CharField(label='名稱', max_length=20,validators=[custom_validate])
pub_date = serializers.DateField(label='發佈日期', required=False)
readcount = serializers.IntegerField(label='閱讀量', required=False)
commentcount = serializers.IntegerField(label='評論量', required=False)
image = serializers.ImageField(label='圖片', required=False)
peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增
- 序列化器對象調用errors
- 序列化器調用validated_data
- 保存
- 若是在驗證成功後,想要基於validated_data完成數據對象的建立,能夠經過實現create()和update()兩個方法來實現。
- class BookInfoSerializer(serializers.Serializer):
"""圖書數據序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
name = serializers.CharField(label='名稱', max_length=20)
pub_date = serializers.DateField(label='發佈日期', required=False)
readcount = serializers.IntegerField(label='閱讀量', required=False)
commentcount = serializers.IntegerField(label='評論量', required=False)
image = serializers.ImageField(label='圖片', required=False)
peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增orm
def create(self, validated_data):
"""新建"""
return BookInfo(**validated_data)對象
def update(self, instance, validated_data):
"""更新,instance爲要更新的對象實例"""
instance.name = validated_data.get('name', instance.name)
instance.pub_date = validated_data.get('pub_date', instance.pub_date)
instance.readcount = validated_data.get('readcount', instance.readcount)
instance.commentcount = validated_data.get('commentcount', instance.commentcount)
return instance
- 若是須要在返回數據對象的時候,也將數據保存到數據庫中,則能夠進行以下修改
- class BookInfoSerializer(serializers.Serializer):
"""圖書數據序列化器"""
id = serializers.IntegerField(label='ID', read_only=True)
name = serializers.CharField(label='名稱', max_length=20)
pub_date = serializers.DateField(label='發佈日期', required=False)
readcount = serializers.IntegerField(label='閱讀量', required=False)
commentcount = serializers.IntegerField(label='評論量', required=False)
image = serializers.ImageField(label='圖片', required=False)
peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增blog
def create(self, validated_data):
"""新建"""
return BookInfo.objects.create(**validated_data)
def update(self, instance, validated_data):
"""更新,instance爲要更新的對象實例"""
instance.name = validated_data.get('name', instance.name)
instance.pub_date = validated_data.get('pub_date', instance.pub_date)
instance.readcount = validated_data.get('readcount', instance.readcount)
instance.commentcount = validated_data.get('commentcount', instance.commentcount)
instance.save()
return instance
- 實現了上述兩個方法後,在反序列化數據的時候,就能夠經過save()方法返回一個數據對象實例了
- serializer.save()
- 若是建立序列化器對象的時候,沒有傳遞instance實例,則調用save()方法的時候,create()被調用,相反,若是傳遞了instance實例,則調用save()方法的時候,update()被調用。
XMind: ZEN - Trial Version