序列化程序中的格式验证错误

Posted

技术标签:

【中文标题】序列化程序中的格式验证错误【英文标题】:Format ValidationError in Serializer 【发布时间】:2016-06-04 07:37:50 【问题描述】:

DjangoRestFramework 似乎以多种方式处理错误。序列化程序类中的 ValidationError 不会始终以相同的方式返回 JSON。

当前响应包含一个 JSON 列表/对象字符串:

"detail":["Unable to log in with provided credentials."]

希望实现:

"detail":"Unable to log in with provided credentials."

我意识到这个响应是默认函数的结果。但是,我已经覆盖了 validate 函数:

class AuthCustomTokenSerializer(serializers.Serializer):
username = serializers.CharField(write_only=True)
password = serializers.CharField(write_only=True)
token = serializers.CharField(read_only=True)

def validate(self, validated_data):
    username = validated_data.get('username')
    password = validated_data.get('password')

    # raise serializers.ValidationError('detail': 'Unable to log in with provided credentials.')

    if username and password:
        user = authenticate(phone_number=username, password=password)

        try:

            if UserInfo.objects.get(phone_number=username):
                userinfo = UserInfo.objects.get(phone_number=username)
                user = User.objects.filter(user=userinfo.user, password=password).latest('date_joined')

            if user:

                if user.is_active:
                    validated_data['user'] = user
                    return validated_data

                else:
                    raise serializers.ValidationError("detail": "User account disabled.")

        except UserInfo.DoesNotExist:
            try:
                user = User.objects.filter(email=username, password=password).latest('date_joined')

                if user.is_active:
                    validated_data['user'] = user
                    return validated_data

            except User.DoesNotExist:
                #raise serializers.ValidationError("s")
                raise serializers.ValidationError('detail': 'Unable to log in with provided credentials.')
    else:
        raise serializers.ValidationError("detail" : "Must include username and password.")

class Meta:
    model = Token
    fields = ("username", "password", "token")

我尝试添加自定义异常处理程序:

from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)

    # Now add the HTTP status code to the response.
    if response is not None:
        response.data['status_code'] = response.status_code


    return response

views.py:if serializer.is_valid(raise_exception=True):

但是,这只会附加当前引发的错误:

"detail":["Unable to log in with provided credentials."],"status_code":400

我应该如何使用更改返回文本的格式? 它只在 validate 函数中为这个特定的序列化程序返回这样的 JSON。

我还研究了格式化 non_field_errors 模板,但它适用于我所有的其他序列化程序,例如:

"detail": "Account exists with email address."

【问题讨论】:

【参考方案1】:

也许您应该尝试覆盖 json 渲染器类并连接一个自定义渲染器类,您可以在其中检查状态代码和 detail 键入响应数据,然后适当地重新格式化该值。

我从未尝试过,所以我无法为您提供确切的代码库,但这是我能想到的唯一获得一致响应的方法。

【讨论】:

我添加了一个自定义 JSON 渲染器类并将其与我的序列化器类一起使用。我已经重新格式化了渲染器,但是如果没有使用 JSON 数组,它的特定情况就不起作用:def render(self, data, accepted_media_type=None, renderer_context=None): data = 'renderer_test' : data['detail'][0] return super(CustomJSONRenderer, self).render(data, accepted_media_type, renderer_context) 返回我正在寻找的内容:"renderer_test":"Unable to log in with provided credentials." 但是得到一个带有“详细信息”的 KeyError 在引发 ValidationErrors 时是否应该有一种简单的方法来避免在 JSON 中使用数组?通过 DRF 的 JSON 错误响应的约定是什么?创建单个对象数组作为所有错误的细节值是否更有意义?

以上是关于序列化程序中的格式验证错误的主要内容,如果未能解决你的问题,请参考以下文章

反序列化

08.DRF-反序列化

Django 表单验证与 DRF 序列化程序验证

Spring框架中的Jackson反序列化错误处理

Java中的序列密钥生成和验证(机器唯一标识符)

通过tidyverts包中的键创建时间序列交叉验证切片