Django Rest Framework为自定义用户错误创建配置文件:'tuple'对象没有属性'_meta'

问题描述 投票:0回答:2

我创建了一个自定义用户,并通过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:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
    raise exc
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\Bragdon\PycharmProjects\version1\users\api\views.py", line 24, in post
    'profile':ProfileSerializer(profile,context=self.get_serializer_context()).data
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\serializers.py", line 562, in data
    ret = super().data
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\serializers.py", line 260, in data
    self._data = self.to_representation(self.instance)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\serializers.py", line 516, in to_representation
    attribute = field.get_attribute(instance)
  File "C:\Users\Bragdon\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\fields.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'.
python django django-rest-framework
2个回答
0
投票

create方法返回user, profile,您只需调用此方法一次,然后使用元组拆包分配userprofile即可


0
投票

serializer.save()中删除重复的RegisterApiView。相反,请执行以下操作。

© www.soinside.com 2019 - 2024. All rights reserved.