Невозможно создать объект 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.