Невозможно создать объект UserProfile для пользователя

У меня есть модель User и модель UserProfile с отношением "один к одному". Я использую сериализатор для создания пользователей и хочу автоматически создавать соответствующий объект UserProfile для каждого пользователя при его создании.

Однако я столкнулся с проблемой, когда объект UserProfile не создается при создании нового пользователя. Несмотря на установку модели UserProfile с отношением OneToOneField к модели User и указание связанного имени "userprofile", я продолжаю получать ошибку, утверждающую, что связанного объекта не существует.

Далее, когда я получаю данные пользователя методом GET с помощью этого сериализатора, поле userprofile отображается как null, хотя я ожидаю, что оно будет содержать связанный объект UserProfile.

Вот мой UserSerializer:

class UserSerializer(serializers.ModelSerializer):
    userprofile = UserProfileSerializer(read_only=True)
    profile_data = serializers.JSONField(write_only=True)

    class Meta:
        model = account_models.User
        fields = (
            "id", "username", "password", "email",
            "is_premium", "premium_time", "userprofile", "profile_data"
        )
        extra_kwargs = {
            "password": {"write_only": True},
        }


    def create(self, validated_data):
        profile_data = validated_data.pop('profile_data')
        image_path = profile_data.pop("image_path", None)
        password = validated_data.pop("password")

        user = account_models.User.objects.create(**validated_data)
        user.set_password(password)
        user.save()

        userprofile = profile_models.UserProfile.objects.create(user=user, **profile_data)

        if image_path:
            save_image(instance=userprofile, image_path=image_path)

        send_notification(user=user, action="CREATE_ACCOUNT")
        return user

А вот соответствующая часть моей модели UserProfile:

class UserProfile(models.Model):
    def image_path(self, filename):
        return f"Users/user_{self.user.id}/{filename}"

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="userprofile")
    fullname = models.CharField(max_length=255)
    biography = models.TextField()
    image = models.ImageField(blank=True, null=True, upload_to=image_path)
    location = models.JSONField(blank=True, null=True)
    verify_code = models.IntegerField(blank=True, null=True)
    verification_timestamp = models.DateTimeField(blank=True, null=True)

Может ли кто-нибудь помочь мне понять, что может быть причиной этой проблемы и как я могу ее решить?

Чтобы автоматически создавать объект UserProfile при создании нового пользователя, вы можете модифицировать метод create следующим образом:

def create(self, validated_data):
    profile_data = validated_data.pop('profile_data', {})
    password = validated_data.pop("password")

    user = account_models.User.objects.create(**validated_data)
    user.set_password(password)
    user.save()

    # Create or update the related UserProfile instance here
    userprofile, created = profile_models.UserProfile.objects.get_or_create(user=user, defaults=profile_data)
    if not created:
        # If the UserProfile object already exists, update it with new data
        for key, value in profile_data.items():
            setattr(userprofile, key, value)
        userprofile.save()

    # ... handle image_path and send_notification as before

    return user

Здесь мы использовали get_or_create() чтобы либо получить существующий объект UserProfile для пользователя, либо создать новый с предоставленными данными профиля. И если объект UserProfile уже существует, мы обновляем его новыми данными.

Дополнительно следует удалить аргумент read_only=True из поля userprofile в вашем сериализаторе, так что:

class UserSerializer(serializers.ModelSerializer):
    userprofile = UserProfileSerializer()  # remove read_only=True
    # ...

Это гарантирует, что поле userprofile будет включено при получении данных пользователя методом GET.

Вернуться на верх