DRF框架serializer之檢視優化
阿新 • • 發佈:2020-07-11
一、create優化
在serializer序列化中,我們通過建立序列化器物件的方式大大地簡化了檢視函式的程式碼,前端傳入的資料通過反序列化操作進行了各種資料校驗,程式碼如下:
from django.http import JsonResponse from django.views import View from django.db import connection import json from .models import Projects from .serializers import ProjectSerializer class ProjectsPage(View):''' 類檢視 ''' def post(self, request): input_data = json.loads(request.body) serializer_check_obj = ProjectSerializer(data=input_data) if not serializer_check_obj.is_valid(): return JsonResponse({"code": 1, "res": "error", "msg": serializer_check_obj.errors}) obj= Projects.objects.create(**serializer_check_obj.validated_data) serializer_obj = ProjectSerializer(instance=obj)
return JsonResponse(serializer_obj.data, status=201)
如上我們可以看到,實際上我們建立了兩個序列化器類物件,一個serializer_check_obj用於反序列化引數校驗(給data傳參),一個serializer_obj用於序列化輸出(給instance傳參),能不能只建立一個序列化器物件就能實現兩個物件的功能呢?答案是可以的,我們可以去掉serializer_obj,然後呼叫serializer_check_obj的save()方法,save()方法會自動呼叫模型類物件中定義的create方法
def post(self, request): input_data = json.loads(request.body) serializer_check_obj = ProjectSerializer(data=input_data) if not serializer_check_obj.is_valid(): return JsonResponse({"code": 1, "res": "error", "msg": serializer_check_obj.errors}) serializer_check_obj.save() return JsonResponse(serializer_check_obj.validated_data, status=201)
模型類中的create方法需要提前定義,該方法是父類的create方法,我們可以進行重寫,父類方法原始碼如下:
在序列化器類中重寫父類的create方法,並返回模型類物件
def create(self, validated_data): obj = Projects.objects.create(**validated_data) return obj
驗證結果:
在呼叫序列化器類物件的save()方法時,也可以傳參,傳參以關鍵字的方式傳入,它會自動新增到create方法的validated_data中,我們可以根據這個引數去進行一些關聯,如判斷當前專案已登入,或者當前這個專案判斷是哪個使用者建立的
二、update優化
原始碼如下:
def put(self, request, pk=None): if pk: update_data = json.loads(request.body) obj = Projects.objects.get(id=pk) serializer_check_obj = ProjectSerializer(data=update_data) if not serializer_check_obj.is_valid(): return JsonResponse({"code": 1, "res": "error", "msg": serializer_check_obj.errors}) obj.name = serializer_check_obj.validated_data.get('name') or obj.name obj.leader = serializer_check_obj.validated_data.get('leader') or obj.leader obj.programmer = serializer_check_obj.validated_data.get('programmer') or obj.programmer obj.tester = serializer_check_obj.validated_data.get('tester') or obj.tester obj.save() serializer_obj = ProjectSerializer(instance=obj) return JsonResponse(serializer_obj.data, status=201)
上面建立了兩個序列化器類的物件,我們也可以進行合併,合併方式跟create有點差別,這裡是給模型類物件同時傳入data和instance,然後呼叫save()方法,它會自動去呼叫序列化器類中的update方法
優化後的put方法:
def put(self, request, pk=None): if pk: update_data = json.loads(request.body) obj = Projects.objects.get(id=pk) serializer_obj = ProjectSerializer(data=update_data, instance=obj) if not serializer_obj.is_valid(): return JsonResponse({"code": 1, "res": "error", "msg": serializer_obj.errors}) serializer_obj.save() return JsonResponse(serializer_obj.data, status=201)
模型類中的update方法需要提前定義,該方法是父類的update方法,我們可以進行重寫,父類方法原始碼如下:
在序列化器類中重寫父類的update方法,並返回模型類物件
def update(self, instance, validated_data): # instance為待更新的模型類物件 # validated_data引數為校驗通過之後的資料 # 必須將更新成功的模型類物件返回 instance.name = validated_data.get('name') or instance.name instance.leader = validated_data.get('leader') or instance.leader instance.programmer = validated_data.get('programmer') or instance.programmer instance.tester = validated_data.get('tester') or instance.tester instance.save() return instance
驗證結果: