一、ModelSerializer序列化
1、定義ModelSerializer序列化器
針對models設計和宣告序列化類
from rest_framework import serializers
from .models import Book, Publisher
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 與Book表對應
# 這三種情況不能同時使用
# 1.取全部欄位
fields = "__all__"
# 2.自定義包含欄位
# fields = ["id", "title", "pub_time"]
# 輸出:[{"id": 1, "title": "python開發", "pub_time": "2011-08-27"},...]
# 3.排除某些欄位
# exclude = ["id", "category","author", "publisher"]
# 輸出:[{"title": "python開發", "pub_time": "2011-08-27"},...]
需要注意的是:取全部欄位、取自定義欄位、排除某些欄位這三種篩選不能同時使用,
2、外鍵關系的序列化
注意:當序列化類META定義了depth時,這個序列化類中參考欄位(外鍵)則自動變為只讀,
depth 代表找嵌套關系的第幾層,
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 與Book表對應
fields = "all"
depth = 1
添加depth前,顯示效果:
添加depth后,顯示效果:
由上圖可知,只會查看嵌套深度一層的內容,
3、自定義欄位
很多欄位默認顯示的是選擇的key值,但要給用戶展示的是value值,
因此可以宣告一些欄位來覆寫默認欄位來進行自定制,
class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到對應中文
class Meta:
model = Book # 與Book表對應
fields = "__all__"
顯示效果如下所示:
4、Meta中其他關鍵字引數
官方檔案地址:https://www.django-rest-framework.org/api-guide/serializers/
(1)指定只讀欄位
希望將多個欄位指定為只讀,推薦使用快捷的Meta選項read_only_fields,而不是顯式地使用read_only=True屬性添加每個欄位,示例如下所示:
class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)
class Meta:
model = Book
fields = "__all__"
depth = 1
read_only_fields = ["id"]
模型欄位有設定 editable=False, AutoField 欄位默認設定為只讀,不需要添加到 read_only_fields 選項,
(2)給欄位添加額外引數——extra_kwargs
使用extra_kwargs引數為ModelSerializer添加或修改原有的選項引數---字典格式,
示例一:
class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)
class Meta:
model = Book
fields = "__all__"
depth = 1
read_only_fields = ["id"]
extra_kwargs = {"title": {"validators": [my_validate,]}}
示例二:
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['email', 'username', 'password']
extra_kwargs = {'password': {'write_only': True}}
如果欄位已在序列化程式類中顯式宣告,則該extra_kwargs選項將被忽略,
5、post和patch請求
由于depth會讓外鍵變成只讀,所以定義一個序列化的類,其實只要去掉depth就可以了,
class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)
class Meta:
model = Book
fields = "__all__"
# fields = ["id", "title", "pub_time"]
# exclude = ["user"]
# 分別是所有欄位 包含某些欄位 排除某些欄位
read_only_fields = ["id"]
extra_kwargs = {"title": {"validators": [my_validate,]}}
6、SerializerMethodField
外鍵關聯的物件有很多欄位是用不到的,都傳給前端會有資料冗余,需要自己去定制序列化外鍵物件的那些欄位,
針對models設計和宣告序列化類
from rest_framework import serializers
from .models import Book, Publisher
class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到對應中文
class Meta:
model = Book # 與Book表對應
fields = "__all__"
查看頁面 http://127.0.0.1:8000/books/list,顯示效果如下所示:
添加 SerializerMethodField的使用,獲取顯示外聯欄位:
class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到對應中文
# SerializerMethodField的使用,獲取顯示外聯欄位
publisher = serializers.SerializerMethodField()
author= serializers.SerializerMethodField()
def get_author(self, obj):
authors_query_set = obj.author.all() # 拿到所有作者資訊
return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set] # 串列推導式
def get_publisher(self, obj):
# obj是我們序列化的每個Book物件
publisher_obj = obj.publisher # 正向查詢
return {'id': publisher_obj.id}
class Meta:
model = Book # 與Book表對應
fields = "__all__"
顯示效果如下所示:
二、ModelSerializer反序列化
1、ModelSerializer原生POST請求
再將 SerDemo/serializers.py 下 BookSerializer 恢復為原生狀態:
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 與Book表對應
fields = "all"
不用自定義create方法,可直接提交提交post請求如下:
資料新增成功,如下所示:
2、SerializerMethodField改寫
class BookSerializer(serializers.ModelSerializer):
# SerializerMethodField的使用,獲取顯示外聯欄位
category_display = serializers.SerializerMethodField(read_only=True) # 重新定義,避免重寫,影響反序列化
publisher_info = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)
def get_category_display(self, obj):
return obj.get_category_display() # ORM方法獲取中文
def get_authors(self, obj):
authors_query_set = obj.author.all() # 拿到所有作者資訊
return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set] # 串列推導式
def get_publisher_info(self, obj):
# obj是我們序列化的每個Book物件
publisher_obj = obj.publisher # 正向查詢
return {'id': publisher_obj.id}
class Meta:
model = Book # 與Book表對應
fields = "__all__"
顯示效果如下所示:
可以從上圖看到,除了顯示了category_display、authors、publisher_info,也顯示了category、publisher、author,
3、extra_kwargs配置欄位引數
class BookSerializer(serializers.ModelSerializer):
# SerializerMethodField的使用,獲取顯示外聯欄位
category_display = serializers.SerializerMethodField(read_only=True) # 重新定義,避免重寫,影響反序列化
publisher_info = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)
def get_category_display(self, obj):
return obj.get_category_display() # ORM方法獲取中文
def get_authors(self, obj):
authors_query_set = obj.author.all() # 拿到所有作者資訊
return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set] # 串列推導式
def get_publisher_info(self, obj):
# obj是我們序列化的每個Book物件
publisher_obj = obj.publisher # 正向查詢
return {'id': publisher_obj.id}
class Meta:
model = Book # 與Book表對應
fields = "__all__"
extra_kwargs = {
"category": {"write_only": True}, # 避免直接改寫
"publisher": {"write_only": True},
"author": {"write_only": True}
}
如此就不再顯示category、publisher、author了,顯示效果如下所示:
三、Serializer與ModelSerializer區別

本文轉載于https://www.cnblogs.com/xiugeng/p/11460855.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/228424.html
標籤:其他
下一篇:9道python基礎練習題
