序列化器:ModelSerializer

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())

這裏會把自動生成的序列化器打印出來。

 


 

指定要包含的字段

如果你只希望在模型序列化程序中使用默認字段的子集,則可以使用 fieldsexclude 選項來完成此操作,就像使用 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',)

fieldsexclude 屬性中的名稱通常映射到模型類的模型字段。

或者 fields 選項中的名稱可以映射成屬性或方法。而不會變成模型類中的參數。

從版本 3.3.0 開始,必須提供其中一個屬性 fieldsexclude

 


 

指定嵌套序列化

默認的 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
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章