混淆使用哪个序列化程序更新用户配置文件 [英] confusion on which serializer to use to update user profile
问题描述
我为用户和用户配置文件创建了序列化程序。
class ProfileSerializer(serializers.ModelSerializer):
/ pre>
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','肤色')
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer(required = True)
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用户数据
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)
#更新配置文件数据
如果不是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()
返回实例
这是我的观点
class UserProfile(APIView) :
pre>
serializer_class = UserSerializer
def get(self,request,token = None,format = None):
返回用户
的配置文件列表$
reply = {}
try:
profile_instance = Profile.objects.filter(user = self.request.user)
如果令牌:
profile = profile_instance.get(token = token)
reply ['data'] = self.serializer_class(profile).data
else:
reply ['data'] = self.serializer_class(profile_instance,许多= True).data
除了:
回复['data'] = []
返回响应(回复,status.HTTP_200_OK)
def post ,请求,令牌=无,格式=无):
更新配置文件
配置文件=无
如果不是令牌无:
try:
profile = Profile.objects.get(user = request.user,token = token)
除了Profile.DoesNotExist:
return error.RequestedResourceNotFound()。as_response()
除了
return error.UnknownError()。as_response()
serialized_data = self.serializer_class(profile,data = request.data,partial = True)
reply = {}
如果不是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响应(reply,status.HTTP_200_OK)
我该怎么办?我的用户配置文件更新?
使用更新功能更新我的UserSerializer
更新与Dean Christian Armada解决方案
class UserProfile(APIView):
serializer_class = ProfileSerializer
def get(self,request,token = None,format = None):
返回用户的配置文件列表
reply = {}
try:
profile_instance = Profile.objects.filter user = self.request.user)
如果令牌:
profile = profile_instance.get(token = token)
reply ['data'] = self.serializer_class(profile).data
else:
回复['data'] = self.serializer_class(profile_instance,many = True).data
除了:
回复['data'] = []
返回响应(reply,status.HTTP_200_OK)
def put(self,request,token = None,* args,** kwargs):
更新a个人资料
print('token',token)
如果令牌:
try:
profile = Profile.objects.get(token = token)
除了
返回响应(status = status.HTTP_400_BAD_REQUEST)
serialized_data = self.serializer_class(profile,data = request.data)
reply = {}
如果serialized_data .is_valid():
profile = serialized_data.save(user = request.user)
reply ['data'] = self.serializer_class(profile,many = False).data
return Response (回复,status.HTTP_200_OK)
else:
返回响应(serialized_data.errors,status.HTTP_400_BAD_REQUEST)
使用你的代码,我得到这个QueryDict实例是不可变的错误
解决方案这是一个使用
PUT
请求方法更新您当前的代码和情况我i更好地使用ProfileSerializer
,因为它有更多的字段。另外,我看到它的方式只有在User对象中有三个字段可以更改,我假设的这三个字段很少被更改。
视图。 py
def put(self,request,* args,** kwargs):
更新配置文件
data = request.data
打印数据
尝试:
profile = Profile.objects.get(token = data.get('token'))
除了:
返回响应(status = status.HTTP_400_BAD_REQUEST)
serializer = self.serializer_class(profile,data = request.data)
如果serializer.is_valid():
serializer.save()
返回响应(serializer.data,status.HTTP_200_OK)
else:
返回响应(序列化程序。错误,
status.HTTP_400_BAD_REQUEST)
serializers.py / p>
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'没有)
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 = {}
如果first_name:
user_inst_fields ['first_name'] = first_name
如果last_name:
user_inst_fields ['last_name'] = last_name
if user_inst_f ields:
User.objects.update_or_create(pk = instance.user.id,
defaults = user_inst_fields)
profile,created = Profile.objects.update_or_create(
token = instance。令牌,默认值= validated_data)
返回配置文件
只需将用户设置为只读它以避免验证
I have a profile model for user to update. I want to have a rest api for that. I have a profile model which is too big than usual. I am working to update the user profile but I am having confusion on which serializer should i use to update the profile. Here is what i have done till now
I created the serializer for user and user profile.
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
This is my view
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)
How should i handle my user profile update?
Updated my UserSerializer with update function
UPDATE with Dean Christian Armada solution
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)
With your code, i get This QueryDict instance is immutable error
解决方案It's a standard to use the
PUT
request method for updating in your current code and situation it is better to use theProfileSerializer
since it has more fields. Also, the way I see it you only have three fields in the User object that can be changed and those three fields I assume is rarely changed.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
Simply just set the user to read only for it to avoid validation
这篇关于混淆使用哪个序列化程序更新用户配置文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!