Django rest_framework Serializer中的create、Views中的create/perform_create的區別
對于后端來說,前后端分離的方式能讓前后端的開發都爽。和所有的爽一樣,每爽一次都要付出一定的代價。而前后端分離的代價,就是后端要面對巨量的模塊化的功能組件以及這些組件的常規用法與重寫復用。有一點經驗,關于[Django rest_framework ] Serializer中的create()、Views中的create()/perform_create()的區別,希望與諸君共討之。
1 Serializer 序列化器
1.1 Serializer作用
序列化器是rest_framework 其中的一個組件,它有兩個功能:
- 序列化:把python中的對象轉成json/xml格式字符串。這里的對象指的是數據庫對象,因為rest_framework 用的ORM來操作數據庫。它的功能直觀上是將數據庫里面的數據,通過接口傳遞到前端,因為使用ORM的緣故,從數據庫到接口數據轉換的過程被描述成序列化,其實更準確的描述應該是[可傳輸化]或者[轉化為可以被前端直接使用的數據類型],這樣更便于理解。
- 反序列化:把json/xml格式字符串轉成python中的對象。從功能上來說,反序列化是序列化的逆過程。但同樣的,從英語到漢語直譯的方式,總會帶來各種理解上的障礙。更準確地描述,應該是[字符串對象化]或者[可存儲化]。
和前后端不分離相比,Serializer承擔了一部分views
2.2 Serializer中的create
序列化()的過程一般是read操作,絕大多數情況下應該不涉及使用create()。所以Serializer重寫create()的情況只能是反序列化(字符串---->數據庫),也就是將接口數據保存到數據庫中。
-
Serializers中的create()方法
from rest_framework import serializersclass MyModelSerializer(serializers.ModelSerializer):"""一個序列化器"""class Meta:model = MyModelfields = '__all__'# Serializers中的create()方法def create(self, validated_data):## your codereturn super().create(validated_data)
上面的這一小段代碼,是一個典型的序列化器,在這里我們重寫了Serializer的create()。可以看到在這里的create()方法有一個validated_data參數,這意味著什么呢,我想聰明的你已經猜到了答案:即這個數據是從前端傳過來并且已經過了驗證(valide)。經過了誰的驗證呢,沒錯,是Serializer。可能許多人還記得Serializer提供了很多字段,類似models中的字段,當時我還在想,我說這玩意兒是用來干嘛的呢。現在回首,我想很多人像我一樣,也已豁然開朗。記著,永遠不要忘記Serializer的功能。舉個例子:
from rest_framework import serializersclass MyModelSerializer(serializers.ModelSerializer):"""一個序列化器"""class Meta:model = MyModelfields = '__all__'# Serializers中的create()方法def create(self, validated_data):## your codereturn super().create(validated_data)# 定義的一個字段my_bool = BooleanField()
上面我定義了一個字段:my_bool 。這個字段可接受的值是一個布爾值(0/1)。如果傳其他值,則會報錯。那么,很明顯的,Serializer中重寫create()方法的作用已然顯現:對Serializer已校驗的前端入參進行二次處理。默認情況下,serializer處理結束后,將會返回一個示例instance給視圖(這一點存疑)。
到此Serializer的作用應該是結束了。
2 Views 視圖
Serializer將校驗成功的數據給到views,views拿到數據之后,用來做持久化。
2.1 views中的create()與perform_create()
在views中你可以重寫create(),并通過request.GET/request.POS/request.data拿到從前端傳過來并經過Serializer規則校驗的數據。
拿到之后呢?你可以對這些數據再次進行處理,或者將它作為調用其它接口的入參(這就是傳說中的對其它系統的接口進行二次封裝)。
視圖中的create(),與序列化器中的create()有一個巨大的區別是:視圖中的create()可以調用perform_create()進行持久化。這很棒棒,因為后端開發說白了就是對數據庫進行增刪改查(撇開使用不同框架的差異),而增刪改查的難易程度事實上取決于你要解決的問題,即實際具體業務的復雜程度。
3 總結一下
- Serializer主要是和前端打交道,so,基于這一點,你重寫Serializer的create(),本質是為了過濾。如果通過了校驗,并且滿足你的要求,那么它會到視圖中做下一步處理(通過過濾);反之,將會給前端反饋一些提示信息過去(被過濾)。
- Views則相反,Views主要和后端打交道,你重寫Views的create(),本質是為了持久化。在持久化之前,你可以對入參做任何符合實際情況的處理(包括調用其它接口),但是因為是POST/create(),最終你還是要持久化(perform_create())。
以上 。