【问题标题】:Django rest_framework custom error messageDjango rest_framework 自定义错误信息
【发布时间】:2018-08-03 04:17:20
【问题描述】:

我有一个 API 端点,它将使用 rest_framework 的 serializer.is_valid() 进行输入验证,并返回自定义错误消息和响应。

serializer = FormSerializer(data=data)
if not serializer.is_valid(raise_exception=False):
    return Response({"Failure": "Error"}, status=status.HTTP_400_BAD_REQUEST)

是否可以在不使用raise_exception=True 提供的通用响应的情况下填充验证错误?我试图避免使用通用响应,因为如果有多个错误,它将显示所有验证错误。

响应将类似于

return Response(
     {
          "Failure": "Error", 
          "Error_list": {"field1": "This field is required"}
     },
     status=status.HTTP_400_BAD_REQUEST
) 

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    创建一个Custom Exception类,

    from rest_framework.exceptions import PermissionDenied
    from rest_framework import status
    
    
    class MyCustomExcpetion(PermissionDenied):
        status_code = status.HTTP_400_BAD_REQUEST
        default_detail = "Custom Exception Message"
        default_code = 'invalid'
    
        def __init__(self, detail, status_code=None):
            self.detail = detail
            if status_code is not None:
                self.status_code = status_code
    


    为什么我继承自 PermissionDenied 异常类??
    看到这个 SO 帖子——Why DRF ValidationError always returns 400

    然后在您的序列化程序中,引发异常,

    class SampleSerializer(serializers.ModelSerializer):
        class Meta:
            fields = '__all__'
            model = SampleModel
    
        def validate_age(self, age):  # field level validation
            if age > 10:
                raise MyCustomExcpetion(detail={"Failure": "error"}, status_code=status.HTTP_400_BAD_REQUEST)
            return age
    
        def validate(self, attrs): # object level validation
            if some_condition:
                raise MyCustomExcpetion(detail={"your": "exception", "some_other": "key"}, status_code=status.HTTP_410_GONE)
            return attrs
    


    agenameSampleModel 类的两个字段


    回复会是这样的


    通过使用此方法,
    1.您可以自定义 JSON 响应
    2.您可以返回任何状态码
    3. serializer.is_valid() 方法中不需要传递True(不推荐)

    【讨论】:

    • 是否可以在对象级验证中捕获字段验证错误?我有 20 多个字段,希望只捕获对象级别验证中的第一个字段验证错误。
    • 根据我的示例,您将通过attrs['your_field'] 获取字段的值。然后自己检查具体验证。如果验证失败,引发 CustomException
    • 所以如果我使用name = serializers.CharField(max_length=10) 作为我的字段验证并在对象级别验证中捕获它是不可能的?
    • 在这种情况下,只有在 is_valid() ->> (@ 987654340@)
    • @Clueless_Coder 有什么问题吗?
    【解决方案2】:

    你可以写自定义error handler:

    from rest_framework.views import exception_handler
    
    def custom_exception_handler(exc, context):
        response = exception_handler(exc, context)
        if response is not None:
            response.data['Failure'] = 'Error'
    
        return response
    

    【讨论】:

    • @JerinPeterGeorge 是的。它只会在响应中添加"Failure": "Error",
    【解决方案3】:

    一种简单的方法是使用其中一条异常消息,例如 NotFound。见docs

    # views.py
    from rest_framework.exceptions import NotFound
    
    class myview(viewsets.ModelViewSet):
        def perform_create(self, serializer):
            raise NotFound("My text here")
    

    这将返回 404 并更改对您的文本的响应

    HTTP 404 Not Found
    Allow: GET, POST, HEAD, OPTIONS
    Content-Type: application/json
    Vary: Accept
    {
        "detail": "my text here"
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-11
      • 2018-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 2018-04-03
      • 2017-01-28
      相关资源
      最近更新 更多