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

Django自定义User与UserProfile模型测试失败求助:创建及更新问题

Django测试失败问题排查与修复

问题1:用户创建测试返回400状态码(预期201)

原因

UserSerializer的create方法直接将包含profile字段的validated_data传给create_user,但User模型的create_user方法无法处理profile参数,且创建User时不会自动生成关联的UserProfile实例,导致序列化验证失败,返回400错误。

修复方案

修改UserSerializer的create方法,先提取profile数据,创建User后再生成对应的UserProfile:

def create(self, validated_data):
    # 先取出profile数据
    profile_data = validated_data.pop('profile')
    # 创建User实例
    user = get_user_model().objects.create_user(**validated_data)
    # 关联创建UserProfile
    UserProfile.objects.create(user=user, **profile_data)
    return user

问题2:已认证用户的UserProfile更新测试中bio字段未更新

原因

  1. 关联名称错误:User模型中UserProfile的related_name是userprofile,但Serializer的update方法中误用了instance.profile,无法找到关联的Profile实例。
  2. 视图未保存数据:ManageUserView的update方法仅验证了Serializer,未调用serializer.save(),导致更新操作未持久化到数据库。
  3. 测试代码疏漏:测试中self.user.refresh_from_db缺少括号,未触发实例刷新(非核心问题,但需修正)。

修复方案

1. 修正UserSerializer的update方法

使用正确的关联名称userprofile,并优化字段更新逻辑:

def update(self, instance, validated_data):
    password = validated_data.pop('password', None)
    if password:
        instance.set_password(password)
        instance.save()

    profile_data = validated_data.pop('profile', None)
    if profile_data is not None:
        # 使用正确的related_name获取Profile实例
        profile = instance.userprofile
        # 用get方法保留原有值,避免覆盖未传入的字段
        profile.picture = profile_data.get('picture', profile.picture)
        profile.bio = profile_data.get('bio', profile.bio)
        profile.dob = profile_data.get('dob', profile.dob)           
        profile.save()
    # 调用父类方法保存User的其他字段
    return super().update(instance, validated_data)

2. 修正ManageUserView的update方法

添加保存逻辑并返回标准响应:

def update(self, request, *args, **kwargs):
    instance = self.get_object()
    serializer = self.get_serializer(instance, data=request.data, partial=True)
    serializer.is_valid(raise_exception=True)
    # 保存序列化后的更新数据
    serializer.save()
    # 返回更新后的实例数据
    return Response(serializer.data)

3. 修正测试代码的实例刷新调用

在test_update_user_profile中补全括号:

self.user.refresh_from_db()  # 补全括号触发实例刷新
self.profile.refresh_from_db()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:52:13