Python 关于使用哪个序列化程序更新用户配置文件的混淆

Python 关于使用哪个序列化程序更新用户配置文件的混淆,python,django,django-rest-framework,Python,Django,Django Rest Framework,我有一个供用户更新的配置文件模型。我想要一个RESTAPI来实现这一点。我有一个侧面模型,它比平常大。我正在努力更新用户配置文件,但我不知道应该使用哪个序列化程序来更新配置文件。这是我到现在为止所做的 我为用户和用户配置文件创建了序列化程序 class ProfileSerializer(serializers.ModelSerializer): class Meta: model = Profile fields = ('token', 'user','

我有一个供用户更新的配置文件模型。我想要一个RESTAPI来实现这一点。我有一个侧面模型,它比平常大。我正在努力更新用户配置文件,但我不知道应该使用哪个序列化程序来更新配置文件。这是我到现在为止所做的

我为用户和用户配置文件创建了序列化程序

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ('token', 'user','current_location', 'permanent_location', 'dob',
                    'about_me', 'gender_status', 'create_profile_for', 'marital_status',
                    'height', 'weight', 'body_type', 'complexion',)


class UserSerializer(serializers.ModelSerializer):
  profile = ProfileSerializer(required=True)
  class Meta:
      model = User
      fields = ('id', 'profile', 'username', 'email', 'first_name', 'last_name',)

  def update(self, instance, validated_data):
      # instance = super(UserSerializer, self).update(validated_data)
      profile_data = validated_data.pop('profile')
      #updating user data
      instance.first_name = validated_data.get('first_name', instance.first_name)
      instance.last_name = validated_data.get('last_name', instance.last_name)
      instance.email = validated_data.get('first_name', instance.email)
      #updating profile data
      if not instance.profile:
          Profile.objects.create(user=instance, **profile_data)
      instance.profile.current_location = profile_data.get('current_location', instance.profile.current_location)
      instance.profile.permanent_location = profile_data.get('permanent_location', instance.profile.permanent_location)
      instance.profile.weight = profile_data.get('weight', instance.profile.weight)
      instance.profile.height = profile_data.get('height', instance.profile.height)
      instance.profile.about_me = profile_data.get('about_me', instance.profile.about_me)
      instance.profile.create_profile_for = profile_data.get('create_profile_for', instance.profile.create_profile_for)
      instance.profile.body_type = profile_data.get('body_type', instance.profile.body_type)
      instance.save()
      return instance
这是我的看法

class UserProfile(APIView):
    serializer_class = UserSerializer
    def get(self, request, token=None, format=None):
        """
        Returns a list of profile of user
        """
        reply={}
        try:
            profile_instance = Profile.objects.filter(user=self.request.user)
            if token:
                profile = profile_instance.get(token=token)
                reply['data'] = self.serializer_class(profile).data
            else:
                reply['data'] = self.serializer_class(profile_instance, many=True).data
        except:
            reply['data']=[]
        return Response(reply, status.HTTP_200_OK)

    def post(self, request, token=None, format=None):
        """
        update a profile
        """
        profile=None
        if not token is None:
            try:
                profile = Profile.objects.get(user=request.user, token=token)
            except Profile.DoesNotExist:
                return error.RequestedResourceNotFound().as_response()
            except:
                return error.UnknownError().as_response()
        serialized_data = self.serializer_class(profile, data=request.data, partial=True)
        reply={}
        if not serialized_data.is_valid():
            return error.ValidationError(serialized_data.errors).as_response()
        else:
            profile = serialized_data.save(user=request.user)
            reply['data']=self.serializer_class(profile, many=False).data
        return Response(reply, status.HTTP_200_OK)
我应该如何处理我的用户配置文件更新

使用更新函数更新了my UserSerializer

更新迪安·克里斯蒂安·阿玛达解决方案

class UserProfile(APIView):
    serializer_class = ProfileSerializer
    def get(self, request, token=None, format=None):
        """
        Returns a list of profile of user
        """
        reply={}
        try:
            profile_instance = Profile.objects.filter(user=self.request.user)
            if token:
                profile = profile_instance.get(token=token)
                reply['data'] = self.serializer_class(profile).data
            else:
                reply['data'] = self.serializer_class(profile_instance, many=True).data
        except:
            reply['data']=[]
        return Response(reply, status.HTTP_200_OK)

    def put(self, request, token=None, *args, **kwargs):
        """
        update a profile
        """
        print('token', token)
        if token:
            try:
                profile = Profile.objects.get(token=token)
            except:
                return Response(status=status.HTTP_400_BAD_REQUEST)
        serialized_data = self.serializer_class(profile, data=request.data)
        reply={}
        if serialized_data.is_valid():
            profile = serialized_data.save(user=request.user)
            reply['data'] = self.serializer_class(profile, many=False).data
            return Response(reply, status.HTTP_200_OK)
        else:
            return Response(serialized_data.errors, status.HTTP_400_BAD_REQUEST)

有了你的代码,我得到这个QueryDict实例是不可变的错误

这是一个标准,可以使用
PUT
请求方法来更新你当前的代码和情况,最好使用
ProfileSerializer
,因为它有更多的字段。另外,在我看来,用户对象中只有三个字段可以更改,而我认为这三个字段很少更改

视图.py

def put(self, request, *args, **kwargs):
    """
    update a profile
    """
    data = request.data
    print data
    try:
        profile = Profile.objects.get(token=data.get('token'))
    except:
        return Response(status=status.HTTP_400_BAD_REQUEST)
    serializer = self.serializer_class(profile, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status.HTTP_200_OK)

    else:
        return Response(serializer.errors,
                        status.HTTP_400_BAD_REQUEST)
class ProfileSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Profile
        fields = ('user', 'height', 'weight', 'token')

    def to_internal_value(self, data):
        first_name = data.pop('first_name', None)
        last_name = data.pop('last_name', None)
        data = super(ProfileSerializer, self).to_internal_value(data)
        data['first_name'] = first_name
        data['last_name'] = last_name
        return data

    def update(self, instance, validated_data):
        first_name = validated_data.pop('first_name', None)
        last_name = validated_data.pop('last_name', None)
        user_inst_fields = {}
        if first_name:
            user_inst_fields['first_name'] = first_name
        if last_name:
            user_inst_fields['last_name'] = last_name
        if user_inst_fields:
            User.objects.update_or_create(pk=instance.user.id,
                                          defaults=user_inst_fields)
        profile, created = Profile.objects.update_or_create(
            token=instance.token, defaults=validated_data)
        return profile
序列化程序.py

def put(self, request, *args, **kwargs):
    """
    update a profile
    """
    data = request.data
    print data
    try:
        profile = Profile.objects.get(token=data.get('token'))
    except:
        return Response(status=status.HTTP_400_BAD_REQUEST)
    serializer = self.serializer_class(profile, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status.HTTP_200_OK)

    else:
        return Response(serializer.errors,
                        status.HTTP_400_BAD_REQUEST)
class ProfileSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Profile
        fields = ('user', 'height', 'weight', 'token')

    def to_internal_value(self, data):
        first_name = data.pop('first_name', None)
        last_name = data.pop('last_name', None)
        data = super(ProfileSerializer, self).to_internal_value(data)
        data['first_name'] = first_name
        data['last_name'] = last_name
        return data

    def update(self, instance, validated_data):
        first_name = validated_data.pop('first_name', None)
        last_name = validated_data.pop('last_name', None)
        user_inst_fields = {}
        if first_name:
            user_inst_fields['first_name'] = first_name
        if last_name:
            user_inst_fields['last_name'] = last_name
        if user_inst_fields:
            User.objects.update_or_create(pk=instance.user.id,
                                          defaults=user_inst_fields)
        profile, created = Profile.objects.update_or_create(
            token=instance.token, defaults=validated_data)
        return profile

只需将用户设置为只读即可避免验证

谢谢您的回答。我不想更新用户,只想更新用户的个人资料,如体重、身高、肤色、位置等。如何使用APIView进行更新?使用ProfileSerializer,我可以更新个人资料,但我可以更新用户名、姓氏、姓氏和电子邮件吗?我已经用您的代码更新了我的问题。我得到一个错误,这个QueryDict实例是不可变的,而且在get中我看不到to_internal_值中定义的名字和姓氏。你能评论一个发送数据的示例吗?让我们来评论一下。