Django Rest Framework自定义注册视图(RegisterView)无法返回令牌+用户数据 [英] Django Rest Framework Custom Register View (RegisterView) failing to return token + user data
问题描述
我在django rest框架应用程序中使用allauth和rest_auth.当注册用户时,将返回令牌(密钥),我要实现的目标是在注册后返回令牌+用户数据. 为此,我具有以下序列化器:
I'm using allauth and rest_auth in my django rest framework app. When registering an user a token (key) is returned, what I'm trying to achieve is to return the token + user data after registration. To do so I've the following serializer:
from rest_framework import serializers
from rest_framework.response import Response
from allauth.account import app_settings as allauth_settings
from allauth.utils import email_address_exists
from allauth.account.adapter import get_adapter
from allauth.account.utils import setup_user_email
from kofiapi.api.users.models import User, UserProfile
from rest_framework.authtoken.models import Token
from rest_auth.models import TokenModel
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('dob', 'phone', 'receive_newsletter')
class UserSerializer(serializers.HyperlinkedModelSerializer):
profile = UserProfileSerializer(required=True)
class Meta:
model = User
fields = ('url',
'email',
'first_name',
'last_name',
'password',
'profile')
extra_kwargs = {'password': {'write_only': True}}
def create_token(self, user):
token, created = Token.objects.get_or_create(user=user)
return token
def create(self, validated_data):
profile_data = validated_data.pop('profile')
password = validated_data.pop('password')
user = User(**validated_data)
user.set_password(password)
user.save()
token = self.create_token(user)
UserProfile.objects.create(user=user, **profile_data)
return user
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile')
profile = instance.profile
instance.email = validated_data.get('email', instance.name)
instance.save()
profile.dob = profile_data.get('dob', profile.dob)
profile.phone = profile_data.get('phone', profile.phone)
profile.receive_newsletter = profile_data.get('receive_newsletter', profile.receive_newsletter)
profile.save()
return instance
class TokenSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField()
class Meta:
model = TokenModel
fields = ('key', 'user')
def get_user(self, instance):
request = self.context.get('request')
serializer_context = {
'request': request,
}
return UserSerializer(request.user, context=serializer_context).data
和以下视图:
from rest_framework.permissions import AllowAny
from kofiapi.api.permissions import IsLoggedInUser, IsAdminUser
from rest_framework.viewsets import ModelViewSet
from rest_auth.registration.views import RegisterView
from rest_framework import viewsets
from kofiapi.api.users.models import User
from kofiapi.api.users.serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
def get_permissions(self):
permission_classes = []
if self.action == 'create':
permission_classes = [AllowAny]
elif self.action == 'retrieve' or self.action == 'update' or self.action == 'partial_update':
permission_classes = [IsLoggedInUser]
elif self.action == 'list' or self.action == 'destroy':
permission_classes = [IsAdminUser]
return [permission() for permission in permission_classes]
class CustomRegisterView(RegisterView):
def get_response_data(self, user):
if allauth_settings.EMAIL_VERIFICATION == allauth_settings.EmailVerificationMethod.MANDATORY:
return {"detail": _("Verification Email Sent")}
if getattr(settings, 'REST_USE_JWT', False):
data = {
'user': user,
'token': self.token
}
return JWTSerializer(data).data
else:
return TokenSerializer(user.auth_token, context={"request": self.request}).data
提交与settings
相关的消息后出现错误,因此我删除了此部分:
I was getting an error after submission related to settings
so I removed this part:
if getattr(settings, 'REST_USE_JWT', False):
data = {
'user': user,
'token': self.token
}
return JWTSerializer(data).data
但是在提交新用户注册后,我现在遇到以下错误:
but upon submitting a new user for registration I'm getting now the following error:
AttributeError at /api/rest-auth/registration/
Got AttributeError when attempting to get a value for field `email` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `AnonymousUser` instance.
Original exception text was: 'AnonymousUser' object has no attribute 'email'.
推荐答案
如果查看rest-auth
的源代码,您会发现在注册过程中,它们不会将用户放在任何位置的请求对象中,这就是为什么您尝试从TokenSerializer
中的request
对象获取用户,它是AnyonymousUser
.
If you look at the source code of rest-auth
you will see that during registration, they don't put user in the request object anywhere, that's why when you try to fetch the user from request
object in your TokenSerializer
it is an AnyonymousUser
.
您可以做的是像在django登录时一样,将上下文中的用户与请求一起传递到自定义视图中,或在请求对象中进行设置.
What you can do is to pass the user in the context along with the request in your custom view or set it in the request object like django does at the time of login.
这篇关于Django Rest Framework自定义注册视图(RegisterView)无法返回令牌+用户数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!