You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF创建用户无Profile字段报错及关联Profile访问问题

Hey there! Let's work through your two issues step by step, using your provided code as context:

Problem 1: KeyError: 'profile' when creating a user without passing the profile field

Root Cause
In your CustomUserSerializer.create() method, you're calling validated_data.pop('profile') directly. If the request doesn't include a profile field, this will throw a KeyError because the key doesn't exist in the validated_data dictionary.

Fix
Modify the create method to safely retrieve the profile data with a default empty dictionary, then create the UserProfile even if no profile data is provided:

def create(self, validated_data):
    # Use pop with a default empty dict to avoid KeyError
    profile_data = validated_data.pop('profile', {})
    user = CustomUser.objects.create(**validated_data)
    # Create UserProfile with the retrieved data (empty dict will use model defaults)
    UserProfile.objects.create(user=user, **profile_data)
    return user

This way, if no profile field is sent in the request, profile_data will be an empty dictionary, and UserProfile.objects.create() will create a profile with all nullable/blank fields set to their default values (null/empty).


Problem 2: Can't access UserProfile properties via user.profile.age

Root Cause
Looking at your UserProfile model, you've set related_name='userProfile' on the OneToOneField to CustomUser. This means the reverse relationship from CustomUser to UserProfile is named userProfile, not profile. So user.profile doesn't exist—you need to use the correct related name.

Fix Options
You have two straightforward options here:

Update the line in verifyUserOtp where you try to access the age:

# Replace this:
print(user.profile.age)
# With this:
print(user.userProfile.age)

Modify the UserProfile model's OneToOneField to use related_name='profile':

class UserProfile(models.Model):
    user = models.OneToOneField(
        CustomUser, primary_key=True, related_name='profile', on_delete=models.CASCADE,)
    # ... rest of your model fields

This will let you use user.profile.age as expected. Additionally, you should fix the update method in your CustomUserSerializer where you incorrectly reference instance.profile and try to set instance.age (a UserProfile field, not a CustomUser field):

def update(self, instance, validated_data):
    profile_data = validated_data.pop('profile', {})
    # Update user data
    instance.first_name = validated_data.get('first_name', instance.first_name)
    instance.last_name = validated_data.get('last_name', instance.last_name)
    instance.email = validated_data.get('email', instance.email)
    instance.save()

    # Update user profile
    profile = instance.profile
    if not profile:
        profile = UserProfile.objects.create(user=instance, **profile_data)
    else:
        profile.age = profile_data.get('age', profile.age)
        profile.gender = profile_data.get('gender', profile.gender)
        profile.save()

    password = validated_data.get('password', None)
    if password:
        instance.set_password(password)
        instance.save()
    update_session_auth_hash(self.context.get('request'), instance)
    return instance

内容的提问来源于stack exchange,提问作者afk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:00:36