DRF 序列化器-Serializer (2)
阿新 • • 發佈:2019-03-19
exc 使用 ring llb print url model 數據保存 根據
作用
1. 序列化,序列化器會把模型對象轉換成字典,經過response以後變成json字符串
2. 完成數據校驗功能
3. 反序列化,把客戶端發送過來的數據,經過request以後變成字典,序列化器可以把字典轉成模型
準備數據模型類booktest/model.py
class BookInfoSerializer(serializers.Serializer): """圖書數據序列化器""" id = serializers.IntegerField(label=‘ID‘, read_only=True) btitle = serializers.CharField(label=‘名稱‘, max_length=20) bpub_date = serializers.DateField(label=‘發布日期‘, required=False) bread = serializers.IntegerField(label=‘閱讀量‘, required=False) bcomment = serializers.IntegerField(label=‘評論量‘, required=False) image = serializers.ImageField(label=‘圖片‘, required=False)
我們為模型類提供一個序列化器.
class BookInfoSerializer(serializers.Serializer): """圖書數據序列化器""" id = serializers.IntegerField(label=‘ID‘, read_only=True) #read_only 僅僅用於讀取數據 btitle = serializers.CharField(label=‘名稱‘, max_length=20) bpub_date = serializers.DateField(label=‘發布日期‘, required=False) bread = serializers.IntegerField(label=‘閱讀量‘, required=False) bcomment = serializers.IntegerField(label=‘評論量‘, required=False) image = serializers.ImageField(label=‘圖片‘, required=False)
二 查詢庫表
常見字段類型
字段構造方式 | |
---|---|
BooleanField | BooleanField() |
NullBooleanField | NullBooleanField() |
CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
RegexField | RegexField(regex, max_length=None, min_length=None, allow_blank=False) |
SlugField | SlugField(maxlength=50, min_length=None, allow_blank=False) 正則字段,驗證正則模式 [a-zA-Z0-9-]+ |
URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
UUIDField | UUIDField(format=‘hex_verbose‘) format: 1) ‘hex_verbose‘ 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) ‘hex‘ 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)‘int‘ - 如: "123456789012312313134124512351145145114" 4)‘urn‘ 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" |
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, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
ListField | ListField(child=, min_length=None, 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頁面時,顯示的字段幫助提示信息 |
Serializer(instance=None, data=empty, **kwarg)
創建序列化器對象
- 參數1: instance=要序列化的模型數據
- 參數2: data=要反序列化器的字典數據
- 參數3: many= 是否要序列化多個模型數據,多條數據many=True,默認一條數據
- 參數4: context=序列化器使用的上下文,字典類型數據,可以通過context把視圖中的數據,傳遞給序列化器內部使用
說明:
2)用於反序列化時,將要被反序列化的數據傳入data參數
3)除了instance和data參數外,在構造Serializer對象時,還可通過context
serializer = AccountSerializer(account, context={
‘request‘: request
}) #把數據傳遞給序列器
-
在客戶端請求時,使用序列化器可以完成對數據的反序列化。
-
五 序列化
三步驟:
1 操作數據庫
2 構造序列化器對象
3 響應數據
class BookInfoView(View): def get(self,request): # 操作數據庫 books = BookInfo.objects.all() # 創建序列化器對象 serializer = BookInfo2Serializer(instance=books,many=True) # 通過 serializer.data 獲取序列化完成以後的數據 print ( serializer.data ) # 返回數據 return JsonResponse(serializer.data,safe=False) #safe=Fase 表示跳過嚴格檢驗數據類型是否為dict
book_qs = BookInfo.objects.all() serializer = BookInfoSerializer(book_qs, many=True) serializer.data # [OrderedDict([(‘id‘, 2), (‘btitle‘, ‘天龍八部‘),
(‘bpub_date‘, ‘1986-07-24‘), (‘bread‘, 36), (‘bcomment‘, 40),
(‘image‘, N]), OrderedDict([(‘id‘, 3), (‘btitle‘, ‘笑傲江湖‘),
(‘bpub_date‘, ‘1995-12-24‘), (‘bread‘, 20), (‘bcomment‘, 80),
(‘image‘ne)]), OrderedDict([(‘id‘, 4), (‘btitle‘, ‘雪山飛狐‘),
(‘bpub_date‘, ‘1987-11-11‘), (‘bread‘, 58), (‘bcomment‘, 24),
(‘ima None)]), OrderedDict([(‘id‘, 5), (‘btitle‘, ‘西遊記‘),
(‘bpub_date‘, ‘1988-01-01‘), (‘bread‘, 10), (‘bcomment‘, 10),
(‘im‘, ‘booktest/xiyouji.png‘)])]
六 反序列化
class BookInfo2Serializer(serializers.Serializer): # 自定義要反序列化的字段 id = serializers.IntegerField(label="主鍵ID",read_only=True) btitle = serializers.CharField(label="標題",required=True,min_length=1,max_length=20,validators=[check_btitle]) bpub_date=serializers.DateField(label="出版日期") bread=serializers.IntegerField(label="閱讀量",min_value=0) bcomment=serializers.IntegerField(label="評論量",default=0) # required=False 反序列化時, 當前字段可以不填 is_delete=serializers.BooleanField(label="邏輯刪除")
- 自定義驗證方法
def validate_btitle(self,data): # 例如,圖書名不能是紅樓夢 if data=="紅樓夢": # 拋出錯誤 raise serializers.ValidationError("紅樓夢是禁書~") # 驗證方法中,把數據值必須返回給字段,否則字段值為空 return data
# 自定義驗證方法[驗證多個或者所有字段,只能出現一次] def validate(self,data): # data 這個是所有字段的內容,字典類型 bread = data.get("bread") bcomment = data.get("bcomment") if bread>=bcomment: return data raise serializers.ValidationError("閱讀量小於評論量,數據太假了") def create(self,validated_data): """保存數據,把字典轉換成模型 validated_data 客戶端提交過來,並經過驗證的數據 """ instance = BookInfo.objects.create( btitle = validated_data.get("btitle"), bread = validated_data.get("bread"), bcomment = validated_data.get("bcomment"), bpub_date = validated_data.get("bpub_date"), is_delete = validated_data.get("is_delete"), )
註意:
1 驗證單個字段,可以有多個方法 2 def validate_<字段名>(self,data): # data當前字段對應的值 3 驗證多個或者所有字段,只能出現一次
(2)反序列化-數據保存view視圖
前面的驗證數據成功後,我們可以使用序列化器來完成數據反序列化的過程.這個過程可以把數據轉成模型類對象.
from django.views import View from django.http import QueryDict from .serializers import BookInfo2Serializer class BookInfo2View(View): def post(self,request): """添加一本圖書""" # 接受數據 data = request.POST # 反序列化 serializer = BookInfo2Serializer(data=data) # 1. 驗證數據 # raise_exception=True 把驗證的錯誤信息返回給客戶端,同時阻止程序繼續往下執行 serializer.is_valid(raise_exception=True) # is_valid調用驗證方式: 字段選項validators->自定義驗證方法[單字段]->自定義驗證方法[多字段] # 驗證成功後的數據 # print(serializer.validated_data) # 2. 轉換數據成模型,同步到數據庫中 result = serializer.save() # save會自動調用序列化器類裏面聲明的create/update方法,返回值是當前新增/更新的模型對象 # 響應數據 return JsonResponse(serializer.data) def put(self,request,pk): """更新一個圖書""" # 根據id主鍵獲取指定圖書信息 book = BookInfo.objects.get(pk=pk) # 獲取put數據 data = QueryDict(request.body) # 使用序列化器完成驗證和反序列化過程 # partial=False接下裏在反序列化中允許部分數據更新 serializer = BookInfo2Serializer(instance=book,data=data,partial=False
) serializer.is_valid(raise_exception=True) serializer.save() # 響應數據 return JsonResponse(serializer.data)
註意:
save之所以可以自動識別,什麽時候執行create ,什麽時候執行update
主要是看創建序列化器對象時,是否有傳入instance參數,
有instance參數,則save會調用序列化器內部的update方法
沒有instance參數,則save會調用序列化器內部的create方法
七 超級版序列化器(ModelSerializer)
serializers.py
from rest_framework import serializers from booktest.models import BookInfo class BookInfoModelSerializer(serializers.ModelSerializer): # 模型序列化器也可以自定義驗證字段[當某些數據不存在於數據庫時,但是需要前端提交過來的,可以進行自定義, # 例如,驗證碼,確認密碼] class Meta: model=BookInfo fields = ["id","btitle"] # 可以給模型序列化器裏面指定的字段設置限制選項 extra_kwargs = { "bread":{"min_length":0,"required":True}, } # 自定義驗證方法[驗證單個字段,可以有多個方法] # def validate_<字段名>(self,data): # data當前字段對應的值 def validate_btitle(self,data): # 例如,圖書名不能是紅樓夢 if data=="紅樓夢": # 拋出錯誤 raise serializers.ValidationError("紅樓夢是禁書~") # 驗證方法中,把數據值必須返回給字段,否則字段值為空 return data # 自定義驗證方法[驗證多個或者所有字段,只能出現一次] def validate(self,data): # data 這個是所有字段的內容,字典類型 bread = data.get("bread") bcomment = data.get("bcomment") if bread>=bcomment: return data raise serializers.ValidationError("閱讀量小於評論量,數據太假了")
views.py
############################################################################################################################### # 3 模型序列化器 # 1. 可以幫我們自動完成字段的聲明[主要是從模型中的字段聲明裏面提取過來] # 2. 模型序列化器也可以幫我們聲明了create和update方法的代碼 ############################################################################################################################### from django.views import View from django.http import JsonResponse from .serializers import BookInfoModelSerializer class BookInfo3View(View): def post(self,request): """添加一本圖書""" # 接受數據 data = request.POST # 反序列化 serializer = BookInfoModelSerializer(data=data) serializer.is_valid(raise_exception=True) result = serializer.save() # 響應數據 return JsonResponse(serializer.data) def put(self,request,pk): """更新一個圖書""" book = BookInfo.objects.get(pk=pk) # 獲取put提交的數據 data = QueryDict(request.body) serializer = BookInfoModelSerializer(instance=book,data=data,partial=True) serializer.is_valid(raise_exception=True) serializer.save() # 響應數據 return JsonResponse(serializer.data)
DRF 序列化器-Serializer (2)