Ошибка Django restframework user email already exists
Я пытаюсь написать представление логина в django restframe для аутентификации пользователя в приложении, но каждый раз, когда я отправляю запрос на сервер, я получаю эту ошибку
`{ 'email': ['email уже существует'] }``
вот как я написал свой сериализатор логинов
class UserLoginSerializer(serializers.ModelSerializer):
full_name: str = serializers.CharField(source='get_name', read_only=True)
tokens: str = serializers.CharField(source='get_token', read_only=True)
class Meta:
model = User
fields = (
'id',
'full_name',
'email',
'password',
'is_superuser',
'is_seller',
'created_at',
'profile_pic',
'tokens'
)
extra_kwargs = {
'password' : {'write_only':True, 'required': True},
'id': {'read_only': True},
'is_superuser': {'read_only': True},
'is_seller': {'read_only': True},
'created_at': {'read_only': True},
'profile_pic': {'read_only': True}
}
def validate(self, data: dict) -> dict:
email: str = data.get('email', '')
password: str = data.get('password', '')
print(password, email)
user: auth = auth.authenticate(email=email, password=password)
print(user)
data = {
'email': user.email,
'tokens': user.get_token()
}
return data
и вот как я написал свой loginapiview
class UserLoginAPIView(generics.GenericAPIView):
serializer_class = UserLoginSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
return Response(serializer.data, status=status.HTTP_200_OK)
Мое предположение заключается в том, что вы используете ModelSerializer
, поэтому встроенный валидатор электронной почты проверяет, как если бы это был вызов create
Это мой сериализатор пользователей электронной почты, бессовестно содранный и отредактированный из rest_framework.authtoken.serializers.AuthTokenSerializer.
Он немного отличается от вашего, так как возвращает user
в validated_data вместо того, чтобы возвращать его непосредственно из функции validate, поэтому внутри представления есть немного лишнего.
from django.contrib.auth import authenticate
from rest_framework import serializers
from django.utils.translation import gettext_lazy as _
class EmailUserLoginSerializer(serializers.Serializer):
"""Email login"""
email = serializers.CharField(label=_("email"), write_only=True)
password = serializers.CharField(
label=_("Password"),
style={"input_type": "password"},
trim_whitespace=False,
write_only=True,
)
token = serializers.CharField(label=_("Token"), read_only=True)
def validate(self, attrs):
"""Validate"""
email = attrs.get("email")
password = attrs.get("password")
if email and password:
user = authenticate(
request=self.context.get("request"),
email=email,
password=password,
)
# The authenticate call simply returns None for is_active=False
# users. (Assuming the default ModelBackend authentication
# backend.)
if not user:
msg = _("Unable to log in with provided credentials.")
raise serializers.ValidationError(msg, code="authorization")
else:
msg = _('Must include "email" and "password".')
raise serializers.ValidationError(msg, code="authorization")
attrs["user"] = user
return attrs
class UserLoginAPIView(generics.GenericAPIView):
serializer_class = EmailUserLoginSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data["user"]
# Note: No need for status=status.HTTP_200_OK as that's the default!
return Response({
"email": user.email,
"tokens": user.get_token(),
})
Потому что вы упоминаете поле email в UserLoginSerializer. Поэтому email требуется в теле post-запроса, иначе сериализатор выдаст ошибку.