使用DRF创建简单的登录api时遇到了问题。登录需要两个字段email
和password
。如果在显示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)
答案 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