ModelSerializer
類提供了一個快捷方式,可讓你基於 Models
自動創建一個 Serializer
類,其中的字段與模型類字段對應。
ModelSerializer
類與常規 Serializer
類相同,不同之處在於:
-
它會根據模型自動生成一組字段。
-
它會自動爲序列化類生成驗證器,例如
unique_together
驗證器。 -
它包含
.create()
和.update()
的簡單默認實現。
聲明 ModelSerializer
如下所示:
from rest_framework import serializers
class AccountSerializer(serializers.ModelSerializer):
class Meta:
# 指定對哪個模型進行序列化
model = Account
# 指定包含哪些字段
fields = ('id', 'account_name', 'users', 'created')
默認情況下,該類中的所有模型類字段將被映射爲相應的序列化類字段。
任何關係(如模型上的外鍵)都將映射到 PrimaryKeyRelatedField
。除非在序列化關係文檔中指定,否則默認不包括反向關係。
檢查 ModelSerializer
序列化類能夠生成一個表示字符串,可以讓你充分檢查其字段的狀態。在使用 ModelSerializer
進行工作時,這是特別有用的,你需要確定它爲你自動創建了哪些字段和驗證器。
爲此,需要進入 Django shell,然後導入序列化類,實例化它並用 repr()
打印對象表示形式:
>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print(repr(serializer))
AccountSerializer():
id = IntegerField(label='ID', read_only=True)
name = CharField(allow_blank=True, max_length=100, required=False)
owner = PrimaryKeyRelatedField(queryset=User.objects.all())
這裏會把自動生成的序列化器打印出來。
指定要包含的字段
如果你只希望在模型序列化程序中使用默認字段的子集,則可以使用 fields
或 exclude
選項來完成此操作,就像使用 ModelForm
一樣。
強烈建議你顯式使用 fields
屬性序列化的所有字段。這將使你不太可能在模型更改時無意中暴露數據。
比如:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('id', 'account_name', 'users', 'created')
你還可以將 fields
屬性設置爲特殊值 '__all__'
,以指示應該使用模型中的所有字段。
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = '__all__'
你可以將 exclude
屬性設置爲從序列化程序中排除的字段列表。
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
exclude = ('users',)
fields
和 exclude
屬性中的名稱通常映射到模型類的模型字段。
或者 fields
選項中的名稱可以映射成屬性或方法。而不會變成模型類中的參數。
從版本 3.3.0 開始,必須提供其中一個屬性 fields
或 exclude
。
指定嵌套序列化
默認的 ModelSerializer
使用主鍵進行關聯,但你也可以使用 depth
選項輕鬆生成嵌套表示(自關聯)。
爲了便於理解,這裏我們用上一篇的 User 和 Profile 的關聯模型來舉例。
# serializers.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('city', 'owner')
depth = 1
現在設定了 depth = 1
,當我們在 shell 中執行下列操作時:
>>> u = Profile.objects.get(pk=1)
>>> serializer = ProfileSerializer(u)
>>> serializer.data
打印出來的 owner
將不僅僅是對應的 User
的主鍵,而是包括該 User 的所有字段:
ReturnDict([('city', 'shanghai'),
('owner',
OrderedDict([('id', 1),
('password','xxx'),
('last_login', '2018-05-03T15:08:04.022687Z'),
('is_superuser', True),
('username', 'diego'),
('first_name', ''),
('last_name', ''),
('email', ''),
('is_staff', True),
('is_active', True),
('date_joined', '2018-04-01T15:01:29.451391Z'),
('groups', []),
('user_permissions', [])]))])
默認情況下 depth = 0
,這時候序列化的關聯對象將只包含該對象的主鍵:
ReturnDict([('city', 'shanghai'), ('owner', 1)])
顯式指定字段
你可以將額外的字段添加到 ModelSerializer
,或者通過在類上聲明字段來覆蓋默認字段,就像你對 Serializer
類所做的那樣。
class AccountSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
groups = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = Account
額外的字段可以對應於模型上的任何屬性或可調用的字段。
指定只讀字段
你可能希望將多個字段指定爲只讀。不要顯式給每個字段添加 read_only = True
屬性,你可以使用快捷方式 Meta
選項 read_only_fields
。
該選項應該是字段名稱的列表或元組,聲明如下:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('id', 'account_name', 'users', 'created')
read_only_fields = ('account_name',)
含有 editable = False
的模型字段,AutoField
字段默認設置爲只讀,並且不需要添加到 read_only_fields
選項。
注意: 有一種特殊情況,只讀字段是模型級別的 unique_together
約束的一部分。在這種情況下,序列化類需要驗證約束該字段,但也不能由用戶編輯。
處理這個問題的正確方法是在序列化類中明確指定字段,同時提供 read_only = True 和 default = ...
關鍵字參數。
其中一個例子是與當前認證 User 的只讀關係,它與另一個標識符是 unique_together
。在這種情況下,你會像這樣聲明用戶字段:
user = serializers.PrimaryKeyRelatedField(
read_only=True,
default=serializers.CurrentUserDefault()
)
其他關鍵字參數
還有一個快捷方式允許你使用 extra_kwargs
選項在字段上指定任意附加關鍵字參數。與 read_only_fields
的情況一樣,這意味着你不需要在序列化類中顯式聲明該字段。
該選項是一個字典,將字段名稱映射到關鍵字參數字典。例如:
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'username', 'password')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User(
email=validated_data['email'],
username=validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user
作者:SingleDiego
鏈接:https://www.jianshu.com/p/099d8c688384
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。