簡體   English   中英

DRF:在 Serializer/ModelSerializer 中創建自定義響應結構哪個更好?

[英]DRF: Which if better to create custom structure of response in Serializer/ModelSerializer?

我目前正在Django Rest Framework上制作一個簡單的CRUD應用程序。

對於特定結構中的任何請求,我需要向客戶端返回響應。

例如,如果客戶端發出創建新記錄的POST請求並執行成功,則 API 需要返回這樣的結構:

{
    "data": [
        {
            "id": 1,
            "email": "bobmarley@gmail.com",
        }
    ],
    "error": {}
}

假設問題與 model 字段有關。 在這種情況下,API 應該返回這樣的結構:

{
    "data": [],
    "error": {
        "email": [
            "This field is required."
        ]
    }
}

如果問題與 model 字段無關,則需要向客戶端返回這樣的結構,其中會有錯誤的描述:

{
    "data": [],
    "error": {
        "non_field_errors": [
            "Description of the error."
        ]
    }
}

根據錯誤,我還必須在查詢響應中返回不同的狀態。

openapi-schema.js:

  /clients:
    post:
      summary: Create New Client
      operationId: post-clients
      responses:
        '200':
          description: Client Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Result'
              examples: {}
        '400':
          description: Missing Required Information
        '409':
          description: Email Already Taken

我當前的代碼返回不正確的結構。 我應該在序列化級別配置所有這些嗎?

{
    "data": [],
    "error": {
        "non_field_errors": [
            "{'email': [ErrorDetail(string='person with this email already exists.', code='unique')]}"
        ]
    }
}

模型.py:

class Client(models.Model):
    id = models.AutoField(primary_key=True)
    email = models.EmailField(unique=True)

    class Meta:
        db_table = "clients"

def __str__(self):
    return self.email

序列化程序.py:

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Client

意見.py:

class ClientView(APIView):
    def post(self, request):
        data = []
        error = {}
        result = {"data": data, "error": error}
        try:
            client_serializer = ClientSerializer(data=request.data)
            client_serializer.is_valid(raise_exception=True)
            client_serializer.save()
            data.append(client_serializer.data)
            return Response(result, status=status.HTTP_201_CREATED)
        except Exception as err:
            error['non_field_errors'] = [str(err)]
            return Response(result, status=status.HTTP_200_OK)

您可以根據需要返回響應數據。

class ClientView(APIView):
    def post(self, request):
        data = []
        error = {}
        result = {"data": data, "error": error}

        try:
            client_serializer = ClientSerializer(data=request.data)

            if not client_serializer.is_valid():
                result["error"] = client_serializer.errors
                return Response(result, status=status.HTTP_400_BAD_REQUEST)

            client_serializer.save()
            data.append(client_serializer.data)
            result["data"] = data
            return Response(result, status=status.HTTP_201_CREATED)

        except Exception as err:
            result["data"] = []
            result["error"] = "Something went wrong"
            return Response(result, status=status.HTTP_200_OK)

這取決於你的身邊

{
    "data": [],
    "error": {
        "email": [
            "This field is required."
        ]
    }
}

我不得不說這有時是錯誤的,因為錯誤可能不同,我的意思是,可能有字符串驗證、基於國家/地區的檢查或其他。

我建議這段代碼

{
    "data": [],
    "error": {
        "non_field_errors": [
            {'email': [ErrorDetail(string='person with this email already exists.', code='unique')]}
        ]
    }
}

在另一種情況下,您可能會遇到錯誤並手動將它們發送到客戶端,例如:

client_serializer = ClientSerializer(data=request.data) 
if client_serializer.is_valid(): 
    return client_serializer.save() 
else: 
    return {"errors": client_serializer.errors} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM