1. 程式人生 > 實用技巧 >DRF框架serializer之檢視優化

DRF框架serializer之檢視優化

一、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

驗證結果: