1. 程式人生 > 程式設計 >Django框架序列化與反序列化操作詳解

Django框架序列化與反序列化操作詳解

本文例項講述了Django框架序列化與反序列化操作。分享給大家供大家參考,具體如下:

Serializer類

1.定義:

Django REST framework中的Serializer使用類來定義,須繼承rest_framework.serializers.Serializer。

例:

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)

2.欄位與選項:

常用欄位型別:

欄位 欄位構造方式
BooleanField BooleanField()
NullBooleanField NullBooleanField()
CharField CharField(max_length=None,min_length=None,allow_blank=False,trim_whitespace=True)
EmailField EmailField(max_length=None,allow_blank=False)
RegexField RegexField(regex,max_length=None,allow_blank=False)
SlugField SlugField(maxlength=50,allow_blank=False) 正則欄位,驗證正則模式 [a-zA-Z0-9-]+
URLField URLField(max_length=200,allow_blank=False)
UUIDField UUIDField(format=‘hex_verbose') format: 1)
IPAddressField IPAddressField(protocol=‘both',unpack_ipv4=False,**options)
IntegerField IntegerField(max_value=None,min_value=None)
FloatField FloatField(max_value=None,min_value=None)
DecimalField DecimalField(max_digits,decimal_places,coerce_to_string=None,max_value=None,min_value=None) max_digits: 最多位數 decimal_palces: 小數點位置
DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT,input_formats=None)
DateField DateField(format=api_settings.DATE_FORMAT,input_formats=None)
TimeField TimeField(format=api_settings.TIME_FORMAT,input_formats=None)
DurationField DurationField()
ChoiceField ChoiceField(choices) choices與Django的用法相同
MultipleChoiceField MultipleChoiceField(choices)
FileField FileField(max_length=None,allow_empty_file=False,use_url=UPLOADED_FILES_USE_URL)
ImageField ImageField(max_length=None,use_url=UPLOADED_FILES_USE_URL)
ListField ListField(child=,max_length=None)
DictField DictField(child=)

選項引數:

引數名稱 作用
max_length 最大長度
min_lenght 最小長度
allow_blank 是否允許為空
trim_whitespace 是否截斷空白字元
max_value 最大值
min_value 最小值

通用引數:

引數名稱 說明
read_only 表明該欄位僅用於序列化輸出,預設False
write_only 表明該欄位僅用於反序列化輸入,預設False
required 表明該欄位在反序列化時必須輸入,預設True
default 反序列化時使用的預設值
allow_null 表明該欄位是否允許傳入None,預設False
validators 該欄位使用的驗證器
error_messages 包含錯誤編號與錯誤資訊的字典
label 用於HTML展示API頁面時,顯示的欄位名稱
help_text 用於HTML展示API頁面時,顯示的欄位幫助提示資訊

3.Serialize物件:

構造方法:

Serializer(instance,data,**kwarg)

(1)用於序列化時,將模型類物件傳入instance引數
(2)用於反序列化時,將要被反序列化的資料傳入data引數
(3)除了instance和data引數外,在構造Serializer物件時,還可通過context引數額外新增資料。

例:

serializer = AccountSerializer(account,context={'request': request})

通過context引數附加的資料,可以通過Serializer物件的context屬性獲取。

序列化

1.基本使用:

(1)查詢物件:
例:

from book.models import BookInfo
book = BookInfo.objects.get(id=4) # 單個物件
books = BookInfo.objects.all() # 多個物件

(2)構造序列化物件:

from book.serializers import BookInfoSerializer
serializer = BookInfoSerializer(book) # 單個物件
serializers = BookInfoSerializer(books,many=True) # 多個物件需要新增many引數

(3)獲取序列化資料:

serializer.data

2.外來鍵巢狀使用:

(1)PrimaryKeyRelatedField:

此欄位將被序列化為關聯物件的主鍵。

book = serializers.PrimaryKeyRelatedField(label='圖書',read_only=True)

或者

book=serializers.PrimaryKeyRelatedField(label='圖書',queryset=BookInfo.objects.all())

指明欄位時需要包含read_only=True或者queryset引數:

  • 包含read_only=True引數時,該欄位將不能用作反序列化使用
  • 包含queryset引數時,將被用作反序列化時引數校驗使用

結果:

{'id': 10,'book': 3,'description': '獨孤九劍','gender': 1,'name': '令狐沖'}

(2)StringRelateField:

此欄位將被序列化為關聯物件的字串表示方式(即__str__方法的返回值)

book = serializers.StringRelatedField(label='圖書')

結果:

{'description': '獨孤九劍','name': '令狐沖','book': '笑傲江湖','id': 10}

(3)使用關聯物件的序列化器:

book = BookInfoSerializer()

結果:

{'book': OrderedDict([('id',3),('name','笑傲江湖'),('pub_date','1995-12-24'),('readcount',28),('commentcount',('image',None)]),'id': 10}

反序列化

1.驗證:

(1)欄位驗證:

from book.serializers import BookInfoSerializer
data = {'pub_date':'2010-1-1','name':'python高階'}
serializer = BookInfoSerializer(data=data)
serializer.is_valid() # 驗證成功返回True,失敗返回False

is_valid()方法還可以在驗證失敗時丟擲異常serializers.ValidationError,可以通過傳遞raise_exception=True引數開啟,REST framework接收到此異常,會向前端返回HTTP 400 Bad Request響應。

(2)欄位選項:

可在序列化器中設定欄位的屬性,來限制資料,對資料進行驗證。

例:

屬性 描述
max_length 字串的最大長度(char)
min_length 字串的最小長度
max_value 最大值(int)
min_value 最小值
required 表明該欄位在反序列化時必須輸入,預設True
default 預設值

(3)單個欄位驗證:

當我們的型別和選項都滿足條件之後,我們需要對單個欄位的值進行校驗,我們在序列化器中實現方法以 validate_ 開頭以欄位名結尾的函式

格式:

def validate_欄位名(self,value):
...
return value

例:

def validate_readcount(self,value):
  if value < 0:
   raise serializers.ValidationError('閱讀量不能為負數')
  # 驗證完成之後,需要將 value返回
  return value

(4)多的欄位驗證:

對多個欄位進行校驗的時候,我們在序列器中實現

格式:

 def validate(self,attrs)
...
  return attrs

例:

def validate(self,data):
  # attrs = data
  # params --> 序列化器data --> attrs
  """
  data = {
   'name':'python','pub_date':'2000-1-1','readcount':10,'commentcount':100
  }
  """
  readcount = data.get('readcount')
  # if readcount<0:
  #  raise serializers.ValidationError()
  commentcount = data.get('commentcount')
  if readcount<commentcount:
   raise serializers.ValidationError('評論量不能大於閱讀量')
  #校驗完成之後,必須要將資料返回回去
  return data

(5)自定義驗證:

在欄位中新增validators選項引數,也可以補充驗證行為

例:

name=serializers.CharField(max_length=20,validators=[custom_validate)]
def custom_validate(self):
if self == 'admin':
raise serializers.ValidationError('admin不可用')
 raise serializers.ValidationError('我就是來搗亂的')

2.儲存:

如果在驗證成功後,想要基於validated_data完成資料物件的建立,可以通過實現create()和update()兩個方法來實現。

(1)create方法:

def create(self,validated_data):
  # validated_data 驗證之後的資料
  # params(前端提交的資料) --> data(序列器接受的資料) --> attrs(多個欄位 校驗) --> validated_data(校驗之後)
  # 如果前段提交的資料 經過序列化器的驗證之後完全滿足需求,則
  # validated_data = params
  """
   validated_data:
  data = {
   'name':'python','readcount':10000,'commentcount':100
  }
  """
  # book = BookInfo()
  # book.save()
  book = BookInfo.objects.create(**validated_data)
  # 需要將建立的物件返回
  return book
( return BookInfo.objects.create(**validated_data)也可)

(2)update方法:

 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.save()
 return instance

實現了上述兩個方法後,在反序列化資料的時候,就可以通過save()方法返回一個數據物件例項了

例:

book = serializer.save()

如果建立序列化器物件的時候,沒有傳遞instance例項,則呼叫save()方法的時候,create()被呼叫,相反,如果傳遞了instance例項,則呼叫save()方法的時候,update()被呼叫。

兩點說明:

1) 在對序列化器進行save()儲存時,可以額外傳遞資料,這些資料可以在create()和update()中的validated_data引數獲取到

serializer.save(owner=request.user)

2)預設序列化器必須傳遞所有required的欄位,否則會丟擲驗證異常。但是我們可以使用partial引數來允許部分欄位更新

serializer = BookInfoSerializer(instance=book,data={'pub_date': '2999-1-1'},partial=True)

模型類序列化器BookModelSerializer

1.定義:

例:

建立一個BookInfoSerializer

class BookInfoSerializer(serializers.ModelSerializer):

 class Meta:
  model = BookInfo
  fields = '__all__'

引數 描述
model 指明參照哪個模型類
fields 指明為模型類的哪些欄位生成

2.指定欄位:

(1)全部欄位:

fields = '__all__'

(2)排除欄位:

exclude = ['xxx','xxxx'...]

(3)指定欄位:

fields = ['xxx','xxxx'...]

(4)只讀欄位:

read_only_fields = ['xxx','xxxx'...]

3.新增額外引數:

可以使用extra_kwargs引數為ModelSerializer新增或修改原有的選項引數

例:

class BookInfoSerializer(serializers.ModelSerializer):
class Meta:
model = BookInfo
 fields = ('id','name','readcount','commentcount')
 read_only_fields = ('id','commentcount')
 extra_kwargs = {
  'readcount': {'min_value': 0,'required': True},'commentcount': {'max_value': 0,}

希望本文所述對大家基於Django框架的Python程式設計有所幫助。