1. 程式人生 > 實用技巧 >drf_序列化工具之 單改與群改(區域性與整體)

drf_序列化工具之 單改與群改(區域性與整體)

1) 單整體改,說明前臺要提供修改的資料,那麼資料就需要校驗,校驗的資料應該在例項化“序列化類物件”時,賦值給data
2)修改,就必須明確被修改的模型類物件,並在例項化“序列化類物件”時,賦值給instance
3)整體修改,所有校驗規則有required=True的欄位,都必須提供,因為在例項化“序列化類物件”時,引數partial預設為False

  注:如果partial值設定為True,就是可以區域性改
1)單整體修改,一般用put請求:
V2BookModelSerializer(
    instance=要被更新的物件, 
    data
=用來更新的資料, partial=預設False,必須的欄位全部參與校驗 ) 2)單區域性修改,一般用patch請求: V2BookModelSerializer( instance=要被更新的物件, data=用來更新的資料, partial=設定True,必須的欄位都變為選填欄位 ) 注:partial設定True的本質就是使欄位 required=True 校驗規則失效 class V2Book(APIView): # 單整體改: 對 v2/books/(pk)/ 傳的資料是與model對應的字典{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() # 目的:將眾多資料的校驗交給序列化類來處理 - 讓序列化類扮演反序列化角色,校驗成功後,序列化類來幫你入庫 book_ser = serializers.V2BookModelSerializer(instance=old_book_obj, data=request_data, partial=False) book_ser.is_valid(raise_exception
=True) # 校驗通過,完成資料的更新:要更新的目標,用來更新的新資料 book_obj = book_ser.save() return Response({ 'status': 0, 'msg': 'ok', 'results': serializers.V2BookModelSerializer(book_obj).data }

單與整體區域性修改


#
重點:ListSerializer與ModelSerializer建立關聯的是: # ModelSerializer的Meta類的 - list_serializer_class class V2BookListSerializer(ListSerializer): def update(self, instance, validated_data): # print(instance) # 要更新的物件們 # print(validated_data) # 更新的物件對應的資料們 # print(self.child) # 服務的模型序列化類 - V2BookModelSerializer for index, obj in enumerate(instance): self.child.update(obj, validated_data[index]) return instance # 原模型序列化類變化 class V2BookModelSerializer(ModelSerializer): class Meta: # ... # 群改,需要設定 自定義ListSerializer,重寫群改的 update 方法 list_serializer_class = V2BookListSerializer
views檢視層:
class
V2Book(APIView): # 單區域性改:對 v2/books/(pk)/ 傳的資料,資料欄位key都是選填 # 群區域性改:對 v2/books/ # 請求資料 - [{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') # 將單改,群改的資料都格式化成 pks=[要需要的物件主鍵標識] | request_data=[每個要修改的物件對應的修改資料] 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: # 遍歷前臺資料[{pk:1, name:123}, {pk:3, price:7}, {pk:7, publish:2}],拿一個個字典 pk = dic.pop('pk', None) if pk: pks.append(pk) else: return Response({ 'status': 1, 'msg': '資料有誤', }) else: return Response({ 'status': 1, 'msg': '資料有誤', }) # pks與request_data資料篩選, # 1)將pks中的沒有對應資料的pk與資料已刪除的pk移除,request_data對應索引位上的資料也移除 # 2)將合理的pks轉換為 objs objs = [] new_request_data = [] for index, pk in enumerate(pks): try: # pk對應的資料合理,將合理的物件儲存 obj = models.Book.objects.get(pk=pk) objs.append(obj) # 對應索引的資料就需要儲存下來 new_request_data.append(request_data[index]) except: # 重點:反面教程 - pk對應的資料有誤,將對應索引的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 })