Django Rest 框架为自定义用户创建配置文件错误:"元组"对象没有属性"_meta"



我做了一个自定义用户,使用knox身份验证,我想为每个用户创建一个配置文件, 这是我对配置文件模型的了解

class Profile(models.Model):
user = models.OneToOneField(User,null=True,on_delete=models.CASCADE)
GENDER = (
('M','Male'),
('F','Female'),
)
username = models.CharField(max_length=150,blank=True)
gender = models.CharField(max_length=1, choices=GENDER,blank=True)
def create(self,user,username):
self.user=user
self.username = username
return self

序列化程序

class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','username','email','phone_number')
class RegisterSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','username','email','phone_number','password')
extra_kwargs = {'password':{'write_only':True}}
def create(self, validated_data):
user = User.objects.create_user(
**validated_data
)
username = validated_data['username']
profile = Profile.objects.create(user=user,username=username)
user.set_password(validated_data['password'])
return user,profile
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
user = authenticate(**data)
if user and user.is_active:
return user
raise serializers.ValidationError('Incorrect Credentials')
#serializer for profile
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ['username','gender']
username = serializers.CharField(source='User.username')

而这是为了视图

class UserApiView(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
serializer_class = UserSerializer
def get_object(self):
return self.request.user
class RegisterApiView(generics.GenericAPIView):
serializer_class = RegisterSerializer
def post(self,request,*args,**kwargs):
serializer = self.get_serializer(data = request.data)
serializer.is_valid(raise_exception=True)
user,profile = serializer.save()
return Response({
'user': UserSerializer(user,context=self.get_serializer_context()).data,
'token':AuthToken.objects.create(user)[1],
'profile':ProfileSerializer(profile,context=self.get_serializer_context()).data
})
class LoginApiView(generics.GenericAPIView):
serializer_class = LoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
class ProfileApiView(generics.RetrieveAPIView):
serializer_class = ProfileSerializer
permission_classes = [permissions.AllowAny]
def get(self,request,*args,**kwargs):
serializer = self.get_serializer(data=request.data)
return Response({
"username":ProfileSerializer(context=self.get_serializer_context()).data
})

另外,我对 drf 和 django 一般比较陌生,我想知道是否有人可以建议更好的做法在注册时为每个用户制作配置文件。

谢谢。

编辑:我尝试执行以下操作:

user,profile = serializer.save()

并生成以下回溯

Traceback (most recent call last):
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesdjangocorehandlersexception.py", line 34, in inner
response = get_response(request)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesdjangocorehandlersbase.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesdjangocorehandlersbase.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesdjangoviewsdecoratorscsrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesdjangoviewsgenericbase.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkviews.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkviews.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkviews.py", line 476, in raise_uncaught_exception
raise exc
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkviews.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:UsersBragdonPycharmProjectsversion1usersapiviews.py", line 24, in post
'profile':ProfileSerializer(profile,context=self.get_serializer_context()).data
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkserializers.py", line 562, in data
ret = super().data
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkserializers.py", line 260, in data
self._data = self.to_representation(self.instance)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkserializers.py", line 516, in to_representation
attribute = field.get_attribute(instance)
File "C:UsersBragdonAppDataLocalProgramsPythonPython37-32libsite-packagesrest_frameworkfields.py", line 487, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `username` on serializer `ProfileSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Profile` instance.
Original exception text was: 'Profile' object has no attribute 'User'.
  1. 在这里,serailizer.save()返回元组(User对象,Profile对象(。因此,请从RegisterApiView中删除重复的serializer.save()。相反,请执行以下操作。

    user, profile = serializer.save()
    
  2. source="User.username"更改为source="user.username"ProfileSerializer

    username = serializers.CharField(source='user.username')
    

create方法返回user, profile,只需调用此方法一次,并使用元组解包分配userprofile

user, profile = serializer.create(serializer.validated_data)

最新更新