日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

序列化模塊ModelSerializer上補充及ListSerializer

 印度阿三17 2019-10-17

整體單改

路由層、模型層、序列化層不需要做修改,只需要處理視圖層:views.py

"""
1) 單整體改,說明前臺要提供修改的數(shù)據(jù),那么數(shù)據(jù)就需要校驗,校驗的數(shù)據(jù)應(yīng)該在實例化“序列化類對象”時,賦值給data
2)修改,就必須明確被修改的模型類對象,并在實例化“序列化類對象”時,賦值給instance
3)整體修改,所有校驗規(guī)則有required=True的字段,都必須提供,因為在實例化“序列化類對象”時,參數(shù)partial默認(rèn)為False


注:如果partial值設(shè)置為True,就是可以局部改
1)單整體修改,一般用put請求:
V2BookModelSerializer(
    instance=要被更新的對象, 
    data=用來更新的數(shù)據(jù),
    partial=默認(rèn)False,必須的字段全部參與校驗
)
2)單局部修改,一般用patch請求:
V2BookModelSerializer(
    instance=要被更新的對象, 
    data=用來更新的數(shù)據(jù),
    partial=設(shè)置True,必須的字段都變?yōu)檫x填字段
)
    注:partial設(shè)置True的本質(zhì)就是使字段 required=True 校驗規(guī)則失效
"""
class V2Book(APIView):
    # 單整體改: 對 v2/books/(pk)/ 傳的數(shù)據(jù)是與model對應(yīng)的字典{name|price|publish|authors}
    def put(self, request, *args, **kwargs):
        request_data = request.data
        pk = kwargs.get('pk')
        old_book_obj = models.Book.objects.filter(pk=pk).first()  # 通過源碼我們知道instance不為none的時候才會走save()中的update,若依我們要拿到這個要更新數(shù)據(jù)的對象,把它賦給instanc
        # 目的:將眾多數(shù)據(jù)的校驗交給序列化類來處理 - 讓序列化類扮演反序列化角色,校驗成功后,序列化類來幫你入庫
        book_ser = serializers.V2BookModelSerializer(instance=old_book_obj, data=request_data, partial=False)
        book_ser.is_valid(raise_exception=True)
        # 校驗通過,完成數(shù)據(jù)的更新:要更新的目標(biāo),用來更新的新數(shù)據(jù)
        book_obj = book_ser.save()

        return Response({
            'status': 0,
            'msg': 'ok',
            'results': serializers.V2BookModelSerializer(book_obj).data
        })

單與整體局部修改

序列化層:serializers.py
# 重點:ListSerializer與ModelSerializer建立關(guān)聯(lián)的是:
# ModelSerializer的Meta類的 - list_serializer_class
class V2BookListSerializer(ListSerializer):
    def update(self, instance, validated_data):
        # print(instance)  # 要更新的對象們
        # print(validated_data)  # 更新的對象對應(yīng)的數(shù)據(jù)們
        # print(self.child)  # 服務(wù)的模型序列化類 - V2BookModelSerializer
        for index, obj in enumerate(instance):
            self.child.update(obj, validated_data[index])
        return instance
    
# 原模型序列化類變化
class V2BookModelSerializer(ModelSerializer):
    class Meta:
        # ...
        # 群改,需要設(shè)置 自定義ListSerializer,重寫群改的 update 方法
        list_serializer_class = V2BookListSerializer
    # ...
視圖層:views.py
class V2Book(APIView):
    # 單局部改:對 v2/books/(pk)/ 傳的數(shù)據(jù),數(shù)據(jù)字段key都是選填
    # 群局部改:對 v2/books/ 
    # 請求數(shù)據(jù) - [{pk:1, name:123}, {pk:3, price:7}, {pk:7, publish:2}]
    def patch(self, request, *args, **kwargs):
        request_data = request.data
        pk = kwargs.get('pk')

        # 將單改,群改的數(shù)據(jù)都格式化成 pks=[要需要的對象主鍵標(biāo)識] | request_data=[每個要修改的對象對應(yīng)的修改數(shù)據(jù)]
        if pk and isinstance(request_data, dict):  # 單改
            pks = [pk, ]
            request_data = [request_data, ]
            
            
        elif not pk and isinstance(request_data, list): # 群改
            pks = []
            for dic in request_data:  # 遍歷前臺數(shù)據(jù)[{pk:1, name:123}, {pk:3, price:7}, {pk:7, publish:2}],拿一個個字典
                #從拿出來的一個個字段中彈出pk的值,如果沒有就返回None
                pk = dic.pop('pk', None)
                # 下面的作用是將pk的值添加到pks中,如果為None的話,直接返回異常,所以能走下的pks和request_data中的數(shù)據(jù)是一一對應(yīng)的
                if pk:
                    pks.append(pk)
                else:
                    return Response({
                        'status': 1,
                        'msg': '數(shù)據(jù)有誤',
                    })
        else:
            return Response({
                'status': 1,
                'msg': '數(shù)據(jù)有誤',
            })

        
        # pks與request_data數(shù)據(jù)篩選,
        # 1)將pks中的沒有對應(yīng)數(shù)據(jù)的pk與數(shù)據(jù)已刪除的pk移除,request_data對應(yīng)索引位上的數(shù)據(jù)也移除
        # 2)將合理的pks轉(zhuǎn)換為 objs
        objs = []
        new_request_data = []
        for index, pk in enumerate(pks):
            try:
                # pk對應(yīng)的數(shù)據(jù)合理,將合理的對象存儲
                obj = models.Book.objects.get(pk=pk)
                objs.append(obj)
                # 對應(yīng)索引的數(shù)據(jù)就需要保存下來
                new_request_data.append(request_data[index])
            except:
                # 重點:反面教程 - pk對應(yīng)的數(shù)據(jù)有誤,將對應(yīng)索引的data中request_data中移除
                # index = pks.index(pk)
                # request_data.pop(index)
                continue

        book_ser = serializers.V2BookModelSerializer(instance=objs, data=new_request_data, partial=True, many=True)
        book_ser.is_valid(raise_exception=True)
        book_objs = book_ser.save()

        return Response({
            'status': 0,
            'msg': 'ok',
            'results': serializers.V2BookModelSerializer(book_objs, many=True).data
        })

總結(jié)

"""
整體修改和局部修改的區(qū)別:partial=True,使字段變成可選字段,也就是不用全都輸入一遍
單整體改時要注意為了走save()中的update也給instance傳對象
單整體和單局部要把pk和request_data變成數(shù)組,并對數(shù)據(jù)進行篩選,然后將pk對應(yīng)的對象取出放在一個數(shù)組里,循環(huán)用pk從數(shù)據(jù)庫中拿出對應(yīng)的對象放入一個對象數(shù)組中(如果出現(xiàn)了數(shù)據(jù)中沒有的PK會報錯),將pk對應(yīng)的request_data的數(shù)據(jù)放入新的數(shù)組,將對象數(shù)組和新的request_data數(shù)組進行反序列化并保存(注意many=True)
"""

?

來源:https://www./content-4-511351.html

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多