首頁(yè)技術(shù)文章正文

DRF框架:序列化器字段類型和選項(xiàng)參數(shù)

更新時(shí)間:2020-08-07 來(lái)源:黑馬程序員 瀏覽量:

1. 字段類型和選項(xiàng)參數(shù)

本篇文章我們來(lái)繼續(xù)學(xué)習(xí)序列化器類定義中的字段類型和選項(xiàng)參數(shù)。

首先我們來(lái)回顧一下序列化器類的基本定義形式:

在定義序列化器類時(shí),我們需要選擇對(duì)應(yīng)的字段類型和設(shè)置對(duì)應(yīng)的選項(xiàng)參數(shù),接下來(lái)我們分別來(lái)進(jìn)行講解。

2. 字段類型

下面的表格中我們列出了序列化器中常用的字段類型,對(duì)于DRF框架中序列化器所有的字段類型,我們可以到 rest_framework.fields 模塊中進(jìn)行查看。

字段字段構(gòu)造方式
BooleanFieldBooleanField()
CharFieldCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailFieldEmailField(max_length=None, min_length=None, allow_blank=False)
IntegerFieldIntegerField(max_value=None, min_value=None)
FloatFieldFloatField(max_value=None, min_value=None)
DecimalField

DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)

max_digits: 最多位數(shù)

decimal_palces: 小數(shù)點(diǎn)位置

DateTimeFieldDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
DateFieldDateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeFieldTimeField(format=api_settings.TIME_FORMAT, input_formats=None)
ChoiceField

ChoiceField(choices)

choices與Django的用法相同

ImageFieldImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)

我們可以發(fā)現(xiàn),序列化器類定義字段類型和Django框架中的字段類型是一樣,我們只需知道常用的字段類型就可以了,對(duì)于其他字段類型,需要的時(shí)候再去查看就可以了。

3. 選項(xiàng)參數(shù)

對(duì)于序列化器字段的選項(xiàng)參數(shù),分別如下兩類:

·通用選項(xiàng)參數(shù):任意字段類型都擁有的參數(shù)

·常用選項(xiàng)參數(shù):特定字段類型才擁有的參數(shù)

3.1 通用選項(xiàng)參數(shù)

通用選項(xiàng)參數(shù)有如下常見(jiàn)參數(shù):

參數(shù)名稱說(shuō)明
read_only默認(rèn)False,若設(shè)置為T(mén)rue,表明對(duì)應(yīng)字段只在序列化操作時(shí)起作用
write_only默認(rèn)False,若設(shè)置為T(mén)rue,表明對(duì)應(yīng)字段只在反序列化操作時(shí)起作用
required默認(rèn)True,表明對(duì)應(yīng)字段在數(shù)據(jù)校驗(yàn)時(shí)必須傳入
default序列化和反序列化時(shí)使用的默認(rèn)值
label用于HTML展示API頁(yè)面時(shí),顯示的字段名稱,理解為對(duì)字段的注釋說(shuō)明即可

對(duì)于這些通用的選項(xiàng)參數(shù),我們需要重點(diǎn)理解里面紅色部分3個(gè)選項(xiàng)參數(shù)的作用,接下來(lái)我們來(lái)對(duì)這些選項(xiàng)參數(shù)做一些具體的介紹。

示例1:read_only參數(shù) (注意對(duì)比設(shè)置之前和設(shè)置之后的效果)

from rest_framework import serializers
class User(object):
    """用戶類"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器類"""
    name = serializers.CharField()
    # 此處將age字段的read_only參數(shù)設(shè)置為T(mén)rue
    age = serializers.IntegerField(read_only=True)
if __name__ == "__main__":
    # 準(zhǔn)備數(shù)據(jù)
    data = {'name': 'laowang', 'age': 18}
    # 數(shù)據(jù)校驗(yàn)
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 獲取校驗(yàn)通過(guò)之后的數(shù)據(jù)
        print('校驗(yàn)通過(guò):', serializer.validated_data)
    else:
        # 獲取校驗(yàn)失敗之后的錯(cuò)誤提示信息
        print('校驗(yàn)失?。?#39;, serializer.errors)


示例結(jié)果:

1596789553423_序列化器01.png

結(jié)果說(shuō)明:

上面的age字段已經(jīng)設(shè)置的read_only=True,所以在反序列化-數(shù)據(jù)校驗(yàn)時(shí)不必傳入,即使傳了,也會(huì)忽略它的存在。

示例2:write_only參數(shù) (注意對(duì)比設(shè)置之前和設(shè)置之后的效果)

from rest_framework import serializers
class User(object):
    """用戶類"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器類"""
    name = serializers.CharField()
    # 此處將age字段的write_only參數(shù)設(shè)置為T(mén)rue
    age = serializers.IntegerField(write_only=True)
if __name__ == "__main__":
    # 創(chuàng)建user對(duì)象
    user = User('smart', 18)
    # 將user對(duì)象序列化為字典{'name': 'smart', 'age': 18}
    serializer = UserSerializer(user)
    # serializer.data獲取序列化之后的字典數(shù)據(jù)
    print(serializer.data)


示例結(jié)果:

1596789565227_序列化器02.png


結(jié)果說(shuō)明:

上面的age字段已經(jīng)設(shè)置的write_only=True,所以在進(jìn)行序列化操作時(shí)會(huì)忽略它的存在,因而上面的序列化之后的數(shù)據(jù)中只會(huì)拿user對(duì)象name屬性的值,而不會(huì)拿user對(duì)象的age屬性的值。

示例3:required參數(shù) (注意對(duì)比設(shè)置之前和設(shè)置之后的效果)

from rest_framework import serializers
class User(object):
    """用戶類"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器類"""
    name = serializers.CharField()
    # 此處age字段的required參數(shù)默認(rèn)為T(mén)rue
    age = serializers.IntegerField()
if __name__ == "__main__":
    # 準(zhǔn)備數(shù)據(jù)
    data = {'name': 'laowang'}
    # 數(shù)據(jù)校驗(yàn)
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 獲取校驗(yàn)通過(guò)之后的數(shù)據(jù)
        print('校驗(yàn)通過(guò):', serializer.validated_data)
    else:
        # 獲取校驗(yàn)失敗之后的錯(cuò)誤提示信息
        print('校驗(yàn)失?。?#39;, serializer.errors)

示例結(jié)果:

1596789575137_序列化器03.png


結(jié)果說(shuō)明:

上面的age字段默認(rèn)required=True,表明數(shù)據(jù)校驗(yàn)時(shí)是必傳的,示例中未傳遞age,所以校驗(yàn)失敗。

將上面示例中age字段的required設(shè)置為False:

from rest_framework import serializers
class User(object):
    """用戶類"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器類"""
    name = serializers.CharField()
    # 此處將age字段的required參數(shù)設(shè)置為False
    age = serializers.IntegerField(required=False)
if __name__ == "__main__":
    # 準(zhǔn)備數(shù)據(jù)
    data = {'name': 'laowang'}
    # 數(shù)據(jù)校驗(yàn)
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 獲取校驗(yàn)通過(guò)之后的數(shù)據(jù)
        print('校驗(yàn)通過(guò):', serializer.validated_data)
    else:
        # 獲取校驗(yàn)失敗之后的錯(cuò)誤提示信息
        print('校驗(yàn)失?。?#39;, serializer.errors)

示例結(jié)果:

1596789585319_序列化器04.png

結(jié)果說(shuō)明:

上面的age字段設(shè)置required=Fasle,表明數(shù)據(jù)校驗(yàn)時(shí)可傳可不傳,示例中未傳遞age,校驗(yàn)也能通過(guò)。

示例4:default參數(shù) (注意對(duì)比設(shè)置之前和設(shè)置之后的效果)

1)序列化時(shí)所使用的默認(rèn)值

from rest_framework import serializers
class User(object):
    """用戶類"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器類"""
    name = serializers.CharField()
    age = serializers.IntegerField()
    addr = serializers.CharField(default='默認(rèn)地址')
if __name__ == "__main__":
    # 創(chuàng)建user對(duì)象
    user = User('smart', 18)
    # 將user對(duì)象序列化為字典{'name': 'smart', 'age': 18}
    serializer = UserSerializer(user)
    # serializer.data獲取序列化之后的字典數(shù)據(jù)
    print(serializer.data)


示例結(jié)果:

1596789596245_序列化器05.png


結(jié)果說(shuō)明:

上面的addr字段設(shè)置了一個(gè)default默認(rèn)值,在序列化user對(duì)象時(shí),因?yàn)閡ser對(duì)象中沒(méi)有addr屬性,所以序列化之后的數(shù)據(jù)中addr使用了默認(rèn)值。

小提示:如果user對(duì)象有addr屬性,則序列化之后的字典中addr的值不再使用default設(shè)置的默認(rèn)值。

2)反序列化時(shí)所使用的默認(rèn)值

from rest_framework import serializers
class User(object):
    """用戶類"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器類"""
    name = serializers.CharField()
    # 注:一旦一個(gè)字段設(shè)置了default,則這個(gè)字段的required默認(rèn)為False
    age = serializers.IntegerField(default=20)
if __name__ == "__main__":
    # 準(zhǔn)備數(shù)據(jù)
    data = {'name': 'laowang'}
    # 數(shù)據(jù)校驗(yàn)
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 獲取校驗(yàn)通過(guò)之后的數(shù)據(jù)
        print('校驗(yàn)通過(guò):', serializer.validated_data)
    else:
        # 獲取校驗(yàn)失敗之后的錯(cuò)誤提示信息
        print('校驗(yàn)失敗:', serializer.errors)

示例結(jié)果:

1596789606758_序列化器06.png


結(jié)果說(shuō)明:

上面的age字段設(shè)置了一個(gè)默認(rèn)值,校驗(yàn)的data字典中未傳遞age數(shù)據(jù),所以校驗(yàn)之后的數(shù)據(jù)中age使用了設(shè)置的默認(rèn)值。

小提示:如果反序列化時(shí)傳遞的data中包含age,則校驗(yàn)之后的字典中age的值不再使用default設(shè)置的默認(rèn)值。

3.2 常用選項(xiàng)參數(shù)

常用的選項(xiàng)參數(shù)有如下幾個(gè)參數(shù):

小提示:以下4個(gè)參數(shù)都是只在數(shù)據(jù)校驗(yàn)時(shí)起作用。

參數(shù)名稱作用
max_length字符串最大長(zhǎng)度
min_length字符串最小長(zhǎng)度
max_value數(shù)字最大值
min_value數(shù)字最小值

參數(shù)說(shuō)明:

·max_length和min_length是針對(duì)字符串類型的參數(shù);

·max_value和min_value是針對(duì)數(shù)字類型的參數(shù)。

示例1:max_length和min_length

示例結(jié)果:

from rest_framework import serializers
class User(object):
    """用戶類"""
    def __init__(self, name, age):
        self.name = name
        self.age = age
class UserSerializer(serializers.Serializer):
    """序列化器類"""
    name = serializers.CharField(min_length=6, max_length=20)
    # 此處age字段的required參數(shù)默認(rèn)為T(mén)rue
    age = serializers.IntegerField()
if __name__ == "__main__":
    # 準(zhǔn)備數(shù)據(jù)
    data = {'name': 'smart'}
    # 數(shù)據(jù)校驗(yàn)
    serializer = UserSerializer(data=data)
    res = serializer.is_valid()
    if res:
        # 獲取校驗(yàn)通過(guò)之后的數(shù)據(jù)
        print('校驗(yàn)通過(guò):', serializer.validated_data)
    else:
        # 獲取校驗(yàn)失敗之后的錯(cuò)誤提示信息
        print('校驗(yàn)失敗:', serializer.errors)


結(jié)果說(shuō)明:

1596789617987_序列化器07.png

上面的name字段設(shè)置了min_length=6和max_length=20兩個(gè)參數(shù),在進(jìn)行數(shù)據(jù)校驗(yàn)時(shí),會(huì)要求name的長(zhǎng)度在6-20之間,因?yàn)槲覀儌鬟f的"smart"長(zhǎng)度為5,所以校驗(yàn)失敗。

4. 內(nèi)容總結(jié)

本次文章我們講解了以下內(nèi)容,大家注意結(jié)合示例代碼來(lái)加強(qiáng)對(duì)一些常見(jiàn)的選項(xiàng)參數(shù)的理解,下次我們來(lái)詳細(xì)講解一下序列化器的序列化功能。

1)常見(jiàn)的字段類型

2)通用選項(xiàng)參數(shù)

3)常用選項(xiàng)參數(shù)


猜你喜歡:

python日志模塊 logging怎么用?

Python單例設(shè)計(jì)模式和企業(yè)級(jí)電商秒殺業(yè)務(wù)解決方案

Python培訓(xùn)課程

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!