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},
}
- extra_kwargs = {
serailizers.Serializer
即可以為數據庫模型類定義,也可以為非數據庫模型類的數據定義
定義Serializer類
定義序列化器
- class BookInfoSerializer(serializers.Serializers)
id = serializers.IntegerField(label='ID', read_only=True) - 字段和選選項
創建Serializer對象
- s = BookInfoSerializer(instance=None, data=empty, **kwarg)
- instance:使用數據庫對象賦值,用於序列化
data:字典類型數據,用於反序列化
- instance:使用數據庫對象賦值,用於序列化
序列化
- 將程序中的數據結構類型轉換為其他類型(字典,JSON,XML)Django中將模型類轉化為JSON
- 基本使用
- 獲取需要序列化的對象
- from book.models import BookInfo
book = BookInfo.objects.get(id=4)- books = BookInfo.objects.all()
- from book.models import BookInfo
- 構造序列化器對象
- from book.serializers import BookInfoSerializer
serializer = BookInfoSerializer(instance=book)- serializer = BookInfoSerializer(instace=books, many=True)
- from book.serializers import BookInfoSerializer
- 獲取序列化數據
- serializer.data
- 獲取需要序列化的對象
- 關聯對象嵌套序列化
- 如果需要序列化的數據中包含有其他關聯對象,則對關聯對象數據的序列化需要指明
- 關聯的對象數據是一個
- PrimaryKeyRelatedFiled
- class PeopleInfoSerializer(serializers.Serializer):
- PrimaryKeyRelatedFiled
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)
- class BookInfoSerializer(serializers.Serializer):
-
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}
反序列化
- 與序列化相反,Django中將JSOn字符串轉化為Django中的模型類對象
- 驗證數據
-
from book.serializers import BookInfoSerializer
-
data = {'pub_date':123}
serializer = BookInfoSerializer(data=data)
serializer.is_valid()
Falseserializer.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
{}
* 使用序列化器進行反序列化時,需要對數據進行驗證后,才能獲取
驗證成功的數據或保存成模型類對象
* 序列化器對象調用is_valid()
* 通過字段類型和選型驗證,驗證成功返回True,失敗返回False
* is_valid(raise_exception=True)
* 驗證失敗后拋出serializers.ValidationError
* 向前端返回HTTP 400 Bad Request響應
* 自定義驗證方法
* validate_<field_name>
* 在序列化器中定義固定方法,驗證單一字段
* 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('我就是來搗亂的')
"""圖書數據序列化器"""
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) # 新增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) # 新增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()被調用。
- 如果在驗證成功后,想要基於validated_data完成數據對象的創建,可以通過實現create()和update()兩個方法來實現。
XMind: ZEN - Trial Version