我有一个个人资料模型供用户更新。我想为此休息一下。我有一个比平常太大的个人资料模型。我正在努力更新用户配置文件,但我对使用哪个序列化程序来更新配置文件感到困惑。这是我到目前为止所做的事情
我为用户和用户个人资料创建了序列化程序。
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)
我该如何处理用户个人资料更新?
使用更新功能更新了我的UserSerializer
与Dean Christian Armada解决方案一起更新
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实例是不可变的错误
答案 0 :(得分:0)
使用PUT
请求方法更新当前代码和情况是一个标准,最好使用ProfileSerializer
,因为它有更多字段。另外,我看到它的方式你只能在User对象中有三个可以改变的字段,而我假设的那三个字段很少被改变。
<强> views.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)
<强> serializers.py 强>
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
只需将用户设置为只读即可避免验证