Расширенные свойства класса пользователя не обновляются

Хотелось бы позволить пользователям обновлять свой профиль, получаем ошибку

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)

и мой serializers.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']

"город" не является атрибутом пользователя, это атрибут профиля. Чтобы 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}}
Вернуться на верх