我有一个 User 模型和一个 UserProfile 模型,具有一对一的关系。我正在使用序列化程序来创建用户,并且我想在创建时自动为每个用户创建相应的 UserProfile 对象。
但是,我遇到了一个问题,即在创建新用户时未创建 UserProfile 对象。尽管使用与用户模型的 OneToOneField 关系设置 UserProfile 模型并将相关名称指定为“userprofile”,但我仍然收到一条错误,指出没有相关对象。
此外,当我使用此序列化程序的 GET 方法检索用户数据时,用户配置文件字段显示为 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
对象或使用提供的 profile_data 创建一个新对象。如果 UserProfile
对象已经存在,我们会使用新数据更新它。
此外,您应该从序列化程序中的
read_only=True
字段中删除 userprofile
参数,因此:
class UserSerializer(serializers.ModelSerializer):
userprofile = UserProfileSerializer() # remove read_only=True
# ...
这将确保使用 GET 方法检索用户数据时包含
userprofile
字段。