【问题标题】:DRF: Custom field error messageDRF:自定义字段错误消息
【发布时间】:2018-03-18 08:07:24
【问题描述】:

在使用 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 answer实现了它仍然无法正常工作。我在做什么错?,现在我的序列化器看起来像:

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)

【问题讨论】:

    标签: python django api django-rest-framework


    【解决方案1】:

    您可以为要覆盖消息的字段设置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."}},
            }
    

    【讨论】:

    • 我已经对帖子进行了编辑,现在我的serializer 看起来如上。按照你的建议做了,不知道我做错了什么。请帮忙
    • 我编辑了我的答案,它不起作用,因为您使用 Serializer 而不是 ModelSerializer
    • 它对我有用,你能用最新的变化更新问题吗?
    • 我从您的问题中使用了您的 LoginSerializer,它工作正常。你也可以添加你的视图,也许你会覆盖其中的一些东西?
    • 添加了views.py文件。
    【解决方案2】:

    你需要field-level-validation,试试吧:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-18
      • 2015-08-03
      • 2020-10-17
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      相关资源
      最近更新 更多