希望允许用户更新他们的配置文件,获得错误
Field name 'city' is not valid for model 'User'.
在上下文中,我扩展了models.py:中的默认用户类
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
city = models.CharField(max_length=50,blank=True)
country = models.CharField(max_length=50, blank=True)
bio = models.CharField(max_length=500, blank=True)
profile_pic = models.ImageField(upload_to='profile/%Y/%m/%d', default='media/placeholder.png', blank=False, null=False)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
当用户更新配置文件时,我在urls.py:中使用此端点
path('update_profile/<int:pk>', views.UpdateProfileView.as_view(), name='update_profile'),
这是我的UpdateProfileView:
class UpdateProfileView(generics.UpdateAPIView):
queryset = User.objects.all()
serializer_class = UpdateUserSerializer
def profile(request):
if request.method == 'PUT':
try:
user = User.objects.get(id=request.user.id)
serializer_user = UpdateUserSerializer(user, many=True)
if serializer_user.is_valid():
serializer_user.save()
return Response(serializer_user)
except User.DoesNotExist:
return Response(data='no such user!', status=status.HTTP_400_BAD_REQUEST)
和我的序列化程序.py:
class UpdateUserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=False)
class Meta:
model = User
fields = ['username', 'email', 'password', 'first_name', 'last_name','city','country']
extra_kwargs = {'username': {'required': False},
'email': {'required': False},
'password': {'required': False},
'first_name': {'required': False},
'last_name': {'required': False},
'city': {'required': False},
'country': {'required': False}}
def validate_email(self, value):
user = self.context['request'].user
if User.objects.exclude(pk=user.pk).filter(email=value).exists():
raise serializers.ValidationError({"email": "This email is already in use."})
return value
def validate_username(self, value):
user = self.context['request'].user
if User.objects.exclude(pk=user.pk).filter(username=value).exists():
raise serializers.ValidationError({"username": "This username is already in use."})
return value
def update(self, instance, validated_data):
#re-writing updated profile info from request
user = self.context['request'].user
if user.pk != instance.pk:
raise serializers.ValidationError({"authorize": "You don't have permission for this user."})
instance.first_name = validated_data['first_name']
instance.last_name = validated_data['last_name']
instance.email = validated_data['email']
instance.username = validated_data['username']
instance.profile.city = validated_data['city']
instance.profile.country = validated_data['country']
instance.profile.bio = validated_data['bio']
instance.save()
return instance
请告诉我哪里出了问题
在序列化程序的这一部分中:
fields = ['username', 'email', 'password', 'first_name', 'last_name','city','country']
"city"不是User的属性,而是Profile的属性。为了让DRF更新它,它需要知道如何访问它
示例:
class UpdateUserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=False)
city = serializers.CharField(source='profile.city')
[...]
就像@Nick ODell说的
">"city"不是User的属性,而是Profile的属性。为了让DRF更新它,它需要知道如何访问它;
但是我们不能像一样改变序列化程序类使用的模型吗
class UpdateUserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=False)
class Meta:
model = Profile
fields = ['username', 'email', 'password', 'first_name', 'last_name','city','country']
extra_kwargs = {'username': {'required': False},
'email': {'required': False},
'password': {'required': False},
'first_name': {'required': False},
'last_name': {'required': False},
'city': {'required': False},
'country': {'required': False}}