DRF:自定义字段错误消息

时间:2017-10-06 13:36:50

标签: python django api django-rest-framework

使用DRF创建简单的登录api时遇到了问题。登录需要两个字段emailpassword。如果在显示json消息后字段留空:

{
    "email": [
        "This field may not be blank."
    ],
    "password": [
        "This field may not be blank."
    ]
}

但我想自定义错误消息,比如说

{
    "email": [
        "Email field may not be blank."
    ],
    "password": [
        "Password field may not be blank."
    ]
}

我在validate()中的serializers.py尝试了以下内容:

if email is None:
            raise serializers.ValidationError(
                'An email address is required to log in.'
            )

但它没有得到override,我不确定原因。

修改

我用@dima实现回答它仍然不起作用。我做错了什么?现在我的序列化器看起来像:

class LoginSerializer(serializers.Serializer):
    email = serializers.CharField(max_length=255, required=True, error_messages={"required": "Email field may not be blank."})
    username = serializers.CharField(max_length=255, read_only=True)
    password = serializers.CharField(max_length=128, write_only=True, required=True,
        error_messages={"required": "Password field may not be blank."})
    token = serializers.CharField(max_length=255, read_only=True)

    def validate(self, data):
        # The `validate` method is where we make sure that the current
        # instance of `LoginSerializer` has "valid". In the case of logging a
        # user in, this means validating that they've provided an email
        # and password and that this combination matches one of the users in
        # our database.
        email = data.get('email', None)
        password = data.get('password', None)
        user = authenticate(username=email, password=password)

        # If no user was found matching this email/password combination then
        # `authenticate` will return `None`. Raise an exception in this case.
        if user is None:
            raise serializers.ValidationError(
                'A user with this email and password was not found.'
            )

        # Django provides a flag on our `User` model called `is_active`. The
        # purpose of this flag is to tell us whether the user has been banned
        # or deactivated. This will almost never be the case, but
        # it is worth checking. Raise an exception in this case.
        if not user.is_active:
            raise serializers.ValidationError(
                'This user has been deactivated.'
            )

        # The `validate` method should return a dictionary of validated data.
        # This is the data that is passed to the `create` and `update` methods
        # that we will see later on.
        return {
            'email': user.email,
            'username': user.username,
            'token': user.token
        }

views.py

class AuthLogin(APIView):
    ''' Manual implementation of login method '''

    permission_classes = (AllowAny,)
    serializer_class = LoginSerializer

    def post(self, request, *args, **kwargs):
        data = request.data
        serializer = LoginSerializer(data=data)
        if serializer.is_valid(raise_exception=True):
            new_data = serializer.data
            return Response(new_data)
        return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

2 个答案:

答案 0 :(得分:2)

您可以为要覆盖邮件的字段设置error_messages属性。在你的情况下:

class LoginSerializer(serializers.Serializer):
    email = serializers.CharField(max_length=255, required=True, error_messages={"required": "Email field may not be blank."})
    username = serializers.CharField(max_length=255, read_only=True)
    password = serializers.CharField(max_length=128, write_only=True, required=True, error_messages={"required": "Password field may not be blank."})
    token = serializers.CharField(max_length=255, read_only=True)

对于ModelSerializers,您可以使用Meta类中的extra_kwargs属性执行此操作。

class SomeModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = SomeModel
        fields = ('email', 'password')
        extra_kwargs = {
            'password': {"error_messages": {"required": "Password field may not be blank."}},
            'email': {"error_messages": {"required": "Email field may not be blank."}},
        }

答案 1 :(得分:1)

您需要field-level-validation,请尝试:

def validate_email(self, value):
#           ^^^^^^
    if not value:
        raise serializers.ValidationError(
            'An email address is required to log in.'
        )
    return value