92 序列化 反序列化
主要內容:
1 反序列化(post請求)
a : 提交post請求, 先確定新增的資料結構,
b: 解決序列化和反序列化的欄位不統一的情框(序列化器中有的欄位, 要序列化的欄位必須有.)
required = False, 只序列化, 不走校驗
read_only: 只走序列化
write_only: 只走反序列化
c: 對於前端傳過來的資料進行校驗. 要觸發反序列化過程中的create方法,
def create(self, validated_data): # 使用orm操作建立物件 book_obj = models.Book.objects.create(title=validated_data['title'],pub_time=validated_data['pub_time'], category=validated_data['post_category'], publisher_id=validated_data['publisher_id']) book_obj.authors.add(*validated_data['authors_list']) return book_obj
d: 通過驗證返回ser_obj.validated_data, 不通過驗證返回ser_obj.errors
2 反序列化put請求
a : 提交put請求, 更新資料
b : 反序列化時, 要把反序列化的物件傳給對應的instance例項, data = request.data, partial=true部分更新.
c : 反序列化跟新時觸發update方法:
def update(self, instance, validated_data): # 使用orm操作編輯物件 print(instance) # 更新的book_obj物件 print(validated_data) # 校驗通過的資料 instance.title = validated_data.get('title', instance.title) instance.pub_time = validated_data.get('pub_time', instance.pub_time) instance.category = validated_data.get('post_category', instance.category) instance.publisher_id = validated_data.get('publisher_id', instance.publisher_id) if validated_data.get('authors_list'): instance.authors.set(validated_data['authors_list']) instance.save() return instance
d : 驗證通過返回ser_obj.validated_data, 不通過返回ser_obj.errors
e : 單個欄位的校驗:(權重中間)
def validate_title(self, value): # value就是title的值 對value處理 if "python" not in value.lower(): raise serializers.ValidationError("標題必須含有python") return value
多個欄位的校驗:(權重最低)
# # 檢驗多個欄位 # def validate(self, attrs): attrs是一個字典 # if 'bad language' not in attrs['title'] and attrs['post_category'] == 1: # return attrs # else: # raise serializers.ValidationError('有敏感資訊')
自定義欄位校驗(權重最高)
def my_validate(value): print('this is validate',value) if '麗麗'in value.lower(): raise serializers.ValidationError('不嚴謹') return value
注意:給欄位配置validators = [my_validate]
class BookSerializer(serializers.Serializer): # # 序列化器中有的欄位物件中必須有 # title = serializers.CharField(max_length=32, validators=[my_validate, ])
3 ModelSerializer: 由於自定義序列化器類比較麻煩, 還要寫create,update方法, 所以引入了ModelSerializer.
a : 定義一個類繼承serializers.ModelSerializer : 會讓你這些所有的外來鍵關係變成read_only = True
b : 在類裡面定義一個meta類,
類裡面的欄位model等於表名,
fieds等於所有的欄位: fields = "__all__"
depth: 表示層級關係, 最好不要超過三級,
extra_kwargs = {'欄位名稱','自定義的引數配置資訊' }
c : 自定義方法欄位: SerializerMethodField() 方法欄位
def get_欄位名稱(self, obj):
obj 每次序列化的模型物件
return 自定義的資料
d : 例項:
自定義校驗方法欄位, 顯示自己需要的內容, 解決depth存在的問題(顯示出全部的內容)
authors = serializers.SerializerMethodField() def get_authors(self, obj): print(obj) author_query = obj.authors.all() return [{'id':author.id, 'name':author.name} for author in author_query]
為了解決序列化和反序列化存在的欄位不一致問題的解決方案:
authors_info = serializers.SerializerMethodField() def get_authors_info(self, obj): authors_query = obj.authors.all() return [{'id':author.id, 'name': author.name} for author in authors_query]
並在meta中設定extra_kwargs = {'對應的欄位':{write_only}: true}(只作為反序列化用)