Ошибка при создании токена аутентификации для нового зарегистрированного пользователя в Django Rest Framework
Я работаю над проектом Django, в котором пытаюсь создать auth-токен для только что зарегистрированного пользователя с помощью Django Rest Framework. Однако при запуске функции register я сталкиваюсь со следующей ошибкой:
ValueError: Cannot assign "<User: Test>": "Token.user" must be a "User" instance.
Вот функция регистра, в которой возникает ошибка:
@api_view(['POST'])
def register(request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
user = User.objects.get(username=request.data['username'])
user.hash_password(request.data['password'])
user.save()
token = Token.objects.create(user=user) # This is where the error occurs
return Response({
'token': token.key,
'User': serializer.data
}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Как исправить эту ошибку и успешно создать токен аутентификации для только что зарегистрированного пользователя?
Я попытался зарегистрировать нового пользователя с помощью функции register в моем представлении Django Rest Framework. Я ожидал, что пользователь успешно зарегистрируется (зарегистрируется в базе данных) и что будет сгенерирован токен аутентификации, связанный с этим пользователем.
Ошибка ValueError: Cannot assign "<User: Test>": "Token.user" must be a "User" instance.
обычно означает, что объект "пользователь" не является экземпляром модели, которую ожидает поле Token.user.
Ваш код кажется правильным, после serializer.save()
возвращаемое значение - экземпляр модели User. Однако hash_password
в строке user.hash_password(request.data['password'])
не является стандартным методом Django для модели User. Пожалуйста, убедитесь, что этот метод существует в вашей модели User и возвращает экземпляр User, а не строку или что-то еще. Кроме того, этот метод, вероятно, выполняет ту же работу, что и set_password
, который уже является частью модели Django User.
Скорее всего, причина в вашем методе hash_password
, проверьте его возвращаемый тип и убедитесь, что он возвращает экземпляр User. Также нет необходимости использовать собственный метод хеширования, поскольку встроенный метод set_password
обеспечивает ту же функциональность.
Пример того, как это будет выглядеть при использовании set_password
:
user.set_password(request.data["password"])
user.save()
Я рекомендую заменить token.objects.create на следующую логику в вашем RegisterView:
from django.urls import reverse
from django.contrib.sites.shortcuts import get_current_site
from rest_framework import generics, status
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken
from .serializers import RegisterSerializer
from .models import User
from .utils import Util
class RegisterView(generics.GenericAPIView):
"""
Register a new user with email and password and send verification email (Student or Tutor)
"""
serializer_class = RegisterSerializer
def post(self, request):
user = request.data
serializer = self.serializer_class(data=user)
serializer.is_valid(raise_exception=True)
serializer.save()
user_data = serializer.data
user = User.objects.get(email=user_data["email"])
refresh_token = RefreshToken.for_user(user)
token = str(refresh_token.access_token)
relative_link = reverse("verify-email")
current_site = get_current_site(request).domain
abs_url = "http://" + current_site + relative_link + "?token=" + token
email_body = "Hi {}! Use the link below to verify your email:\n{}".format(
user.full_name, abs_url)
data = {
"to_email": user.email,
"email_body": email_body,
"email_subject": "Verify your email",
}
Util.send_email(data)
return Response(user_data, status=status.HTTP_201_CREATED)
Эта логика позволяет создать пользователя и отправляет письмо для проверки электронной почты. Убедитесь, что в вашем проекте Django настроены необходимые импорты и конфигурации.