Как изменить имя пользователя по умолчанию на email, в DRF получить токен для входа?

Это мой путь для входа

from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
     ...
    path('login/', obtain_auth_token), 
]

Когда я использую это как логин, он принимает имя пользователя (хотя он принимает email как данные поля) & пароль и генерирует токен для меня

{
    "username": "manig@gmail.com",
    "password" : "manig@gmail.com"
}

как я хочу

{
    "email": "manig@gmail.com", 
    "password" : "manig@gmail.com"
}

Я хочу заменить имя пользователя на email!!! как мне это изменить?

Что я пробовал до сих пор: Я сделал пользовательский сериализатор

class AuthTokenSerializer(serializers.ModelSerializer):
    class Meta:
        model = AuthUser
        fields = ('email', 'password')
        extra_kwargs = {'password': {'write_only': True}}
    
    def validate(self, data):
        user_obj = None
        email = data.get('email')
        password = data.get('password')
        if email and password:
            user_obj = AuthUser.objects.filter(email=email).first()
            if not user_obj:
                raise serializers.ValidationError("This email is not registered")
            if not user_obj.check_password(password):
                raise serializers.ValidationError("Incorrect credentials")
        return data
    
    def create(self, validated_data):
        user = AuthUser.objects.get(email=validated_data['email'])
        refresh = RefreshToken.for_user(user)
        return {
            'user': user,
            'token': str(refresh.access_token)
        }

А вот вид для него

class AuthLoginUser(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        serializer = AuthTokenSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'token': token.key,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'email': user.email,
            'role': user.role
            })

Вот как выглядит шаблон url

urlpatterns = [
    ...
    path('login/', views.AuthLoginUser.as_view()),
] 

Когда я делаю это, он заменяет поле username на email, но когда я вхожу в систему/передаю данные через конечную точку

Ошибка, которую я получаю, и которую я не должен получать

Он начинает выдавать мне эту ошибку, пользователь с таким email уже существует, вместо этого он должен был ответить с токеном, именем, фамилией, email и ролью, в соответствии с пользовательским сериализатором и классом представления.

Помогите, пожалуйста, решить эту проблему

Вы должны использовать ModelSerializer.create только для создания новых экземпляров; вы получаете эту ошибку, потому что сериализатор выполняет проверку, как будто вы создаете новый экземпляр. Измените свой сериализатор:

class AuthTokenSerializer(serializers.Serializer):
    email = serializers.EmailField(write_only=True)
    password = serializers.CharField(write_only=True, style={'input_type': 'password'})
    
    def validate(self, data):
        email = data.get('email')
        password = data.get('password')

        if email and password:
            try:
               user_obj = AuthUser.objects.get(email=email)
               if not user_obj.check_password(password):
                  raise serializers.ValidationError("Incorrect credentials")
               data['user'] = user_obj
            except AuthUser.DoesNotExist:
               raise serializers.ValidationError("This email is not registered")
        else:
            raise serializers.ValidationError("Missing credentials")
        return data
      
    def save(self):
        user = AuthUser.objects.get(email=self.validated_data['email'])
        refresh = RefreshToken.for_user(user)
        return {
            'user': user,
            'token': str(refresh.access_token)
        }

Я скорректировал валидацию и поместил код create внутри метода save, но я думаю, что вы можете удалить save, поскольку вы не используете его в вашем представлении.

Вернуться на верх