DRF框架之Serializer序列化器的反序列化操作


昨天,我們完成了Serializer序列化器的反序列化操作,那么今天我們就來學習Serializer序列化器的最后一點知識,反序列化操作。

首先,我們定要明確什么是反序列化操作?

反序列化操作:JOSN數據 --> 字典數據 -->驗證通過的字典數據 --> 模型數據

我們在進行反序列化操作時,首先要保證就是拿到的字典數據一定要通過認證。

反序列化操作的步驟:

1. 定義一個序列化器(這里我們采用昨天定義好的序列化器即可)。

class BookInfoSerializer(serializers.Serializer):
    '''定義圖書序Serializer序列化器'''
    # 這里的字段需要和模型類中的字段名、字段類型、約束一致
    id = serializers.IntegerField(label='ID', read_only=True)
    btitle = serializers.CharField(label='名稱', max_length=20)
    bpub_date = serializers.DateField(label='發布日期', required=False)
    bread = serializers.IntegerField(label='閱讀量', required=False)
    bcomment = serializers.IntegerField(label='評論量', required=False)

2. 准備JSON數據或字典數據

data = {'btitle':'大話西游','bpub_date':'2020-02-06'}

3. 驗證字典數據

我們使用序列化器對象點出is_valid()方法進行驗證,驗證成功返回True,否則返回False。

3.1 驗證通過

當字典數據通過校驗時,我們可以通過序列化器對象點出validated_data屬性獲取到校驗成功后的字典數據

>>> data = {'btitle':'大話西游','bpub_date':'2020-02-06'}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([('btitle', '大話西游'), ('bpub_date', datetime.date(2020, 2, 6))])

3.2 驗證未通過

當字典數據未通過校驗時,我們可以通過序列化器對象點出errors屬性獲取到錯誤信息

>>> data = {'bpub_date': 123}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.validated_data
{}
>>> s.errors
{'btitle': [ErrorDetail(string='This field is required.', code='required')], 'bpub_date': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY-MM-DD.', code='invalid')]}

3.3 對單一字段進行驗證

我們需要在序列化器類中定義一個名字為(validate_字段名)的方法,來補充驗證邏輯。

def validate_btitle(self, value):
    '''
    對btitle字段進行驗補充
    :param value: 前段傳遞的btitle數據
    :return: 驗證成功:返回value;驗證失敗:返回錯誤信息
    '''   

當驗證失敗時,我們使用raise拋出異常的方式來返回錯誤信息。

例如:

    # 補充單一字段的驗證邏輯
    def validate_btitle(self, value):
        '''
        對btitle字段進行驗補充
        :param value: 前段傳遞的btitle數據
        :return: 驗證成功:返回value;驗證失敗:返回錯誤信息
        '''

        # 驗證邏輯
        if 'django' not in value:
            # 失敗
            raise serializers.ValidationError('btitle數據錯誤信息')

        # 成功
        return value

Shell測試代碼:

>>> from booktest.serializers import BookInfoSerializer
>>> data = {'btitle': 'python'}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{'btitle': [ErrorDetail(string='btitle數據錯誤信息', code='invalid')]}
>>> data = {'btitle': 'python_django'}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([('btitle', 'python_django')])

3.4 對所有字段進行擴展驗證

我們需要在序列化器中定義一個名字為(validate())的方法,來補充對所有字段進行擴展驗證的邏輯。

def validate(self, attrs):
        '''
        對多個字段進行驗證
        :param attrs: 前段傳遞的字典數據
        :return: 驗證成功:返回attrs;驗證失敗:返回錯誤信息
        '''

同樣,我們也需要使用raise拋出異常信息。

例如:

def validate(self, attrs):
        '''
        對多個字段進行驗證
        :param attrs: 前段傳遞的字典數據
        :return: 驗證成功:返回attrs;驗證失敗:返回錯誤信息
        '''

        # 驗證邏輯:這里需要驗證的是bread大於bcomment
        bread = attrs.get('bread')
        bcomment = attrs.get('bcomment')

        if bread < bcomment:
            # 失敗
            raise serializers.ValidationError('bread需要大於bcomment')

        # 成功
        return attrs

Shell測試代碼:

>>> from booktest.serializers import BookInfoSerializer
>>> data = {'btitle': 'about django', 'bread': 10, 'bcomment': 20}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
False
>>> s.errors
{'non_field_errors': [ErrorDetail(string='bread需要大於bcomment', code='invalid')]}
>>> data = {'btitle': 'about django', 'bread': 50, 'bcomment': 20}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([('btitle', 'about django'), ('bread', 50), ('bcomment', 20)])

4. 驗證后的字典數據 ---> 模型數據

這里,我們已將到了數據反序列化的最后一步操作了。

同樣,我們也應該知道,將驗證后的字典數據轉模型數據的實質,其實就是將驗證過的字典數據添加到數據庫中。

那么,對於將數據保存到數據庫中的操作一共就兩種:一種是添加數據的操作,一種是修改數據的操作。

4.1 添加數據

我們,想要添加數據,就需要在序列化器類中定義一個create()方法。

def create(self, validated_data):
        '''
        序列化器進行新增數據的方法
        :param validated_data: 通過驗證的字典數據
        :return:根據RESTful設計方式,需要將添加的數據返回
        '''
        
        return ORM添加數據的語句(模型類.objects.create(**validated_data))

例如:

def create(self, validated_data):
        '''
        序列化器進行新增數據的方法
        :param validated_data: 通過驗證的字典數據
        :return:根據RESTful設計方式,需要將添加的數據返回
        '''

        return BookInfo.objects.create(**validated_data)

在這里,我們需要返回添加的數據給前端,因為我們定義的API是遵守RESTful設計風格的。

Shell測試代碼:

>>> from booktest.serializers import BookInfoSerializer
>>> data = {'btitle': 'django手冊', 'bpub_date': '2020-02-05', 'bread': 20, 'bcomment': 10}
>>> s = BookInfoSerializer(data=data)
>>> s.is_valid()
True
>>> s.save()
<BookInfo: django手冊>

注意:

當我們創建序列化對象時,只傳遞data數據,就表示我們需要向數據庫里添加數據

所以,當序列化器對象調用save()方法時,會自動調用序列化器類中的create()方法

4.2 修改數據

我們,想要修改數據時,需要在序列化器類中定義一個update()方法。

    def update(self, instance, validated_data):
        '''
        序列化器進行修改數據的方法
        :param instance: 需要修改的模型對象
        :param validated_data: 前端傳遞的字典數據
        :return: 根據RESTful設計方式,需要將修改的數據返回
        '''
        
        # 新值覆蓋舊值
        instance.字段名 = validated_data.get(字段名)
        instance.save()
        return instance

例如:

def update(self, instance, validated_data):
        '''
        序列化器進行修改數據的方法
        :param instance: 需要修改的模型對象
        :param validated_data: 前端傳遞的字典數據
        :return: 根據RESTful設計方式,需要將修改的數據返回
        '''

        # 新值覆蓋舊值
        instance.btitle = validated_data.get('btitle')
        instance.bpub_date = validated_data.get('bpub_date')
        instance.bread = validated_data.get('bread')
        instance.bcomment = validated_data.get('bcomment')
        instance.save()

        return instance

我們同樣也需要將修改的數據返回給前端。

Shell測試代碼:

from booktest.models import BookInfo
from booktest.serializers import BookInfoSerializer
>>> book = BookInfo.objects.get(id=10)
>>> data = {'btitle': 'python_django手冊', 'bpub_date': '2020-02-05', 'bread': 20, 'bcomment': 10}
>>> s = BookInfoSerializer(instance=book,data=data)
>>> s.is_valid()
True
>>> s.save()
<BookInfo: python_django手冊>

注意:

當我們創建序列化器對象時,傳遞了instancedata數據,就表示我們需要進行數據的修改操作。

所以,當我們使用序列化器對象調用save()方法時,會自動調用序列化器類中的update()方法。

至此,我們的Serializer序列化的反序列化操作就學習完畢了。

序列化器的學習中,幾乎沒有什么邏輯點,因為,使用的是他人已經封裝好的框架,所以必須遵守框架的規定來開發,只需要,記住模版即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM