整體單改路由層、模型層、序列化層不需要做修改,只需要處理視圖層: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.pyclass 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 |
|