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

测试PadLock修改功能遇AnonymousUser属性缺失,求解决方案

问题根源

测试用例未登录用户就发起请求,导致视图中request.user为AnonymousUser,而AnonymousUser没有自定义的user_locked_with属性,直接访问触发报错。同时视图本身未做登录校验,允许匿名用户进入执行后续逻辑。

解决方法(无需重写AnonymousUser)

1. 修复测试用例:登录指定用户

编辑PadLock的操作需要已登录用户执行,测试时必须先登录对应用户,同时注意create_user需传入密码参数(否则无法登录):

class UpadtePadlockTest(TestCase):
    username = "testusername"
    email = "testuser@name.com"
    password = "testpass123"  # 添加登录密码
    username2 = "testusername2"
    email2 = "testuser2@name.com"
    password2 = "testpass456"  # 添加登录密码

    def test_update_padlock(self):
        User = get_user_model()    
        user1 = User.objects.create_user(
            self.username, self.email, self.password  # 传入密码
        )
        user2 = User.objects.create_user(
            self.username2, self.email2, self.password2, 
            user_locked_with=user1.username  # 存储用户名而非用户对象
        )
        user1.user_locked_with = user2.username  # 存储用户名而非用户对象
        user1.save()
        
        new_padlock= PadLock.objects.create(
            start_date=datetime.date.today(),
            motto_field="Jodo is my motto",
            creator=user1,
            modifier=user2
        )
        
        # 登录用户(这里以登录创建者user1为例)
        self.client.login(username=self.username, password=self.password)
        
        response = self.client.post(
            reverse('edit_padlock'),
            {'start_date':datetime.date.today(),
             'motto_field':"Jodo is not my motto"}
        )
        
        self.assertEqual(response.status_code,302)

        new_padlock.refresh_from_db()
        self.assertEqual(new_padlock.motto_field,"Jodo is not my motto")

2. 优化视图:添加登录校验

给edit_padlock视图添加@login_required装饰器,拦截匿名用户访问,从根源避免触发错误:

from django.contrib.auth.decorators import login_required

@login_required  # 添加登录校验装饰器
def edit_padlock(request):
    context ={}
    user = request.user 
    # 额外处理user_locked_with为空或关联用户不存在的情况,避免后续报错
    if not user.user_locked_with:
        return HttpResponseRedirect("/invalid-lock/")
    
    try:
        user2 = CustomUser.objects.get(username=user.user_locked_with)
    except CustomUser.DoesNotExist:
        return HttpResponseRedirect("/invalid-lock/")
    
    # 后续原有逻辑...

可选优化:修正字段关联类型

当前user_locked_with用CharField存储用户名不符合数据库设计规范,建议改为ForeignKey关联自身,避免字符串存储的不一致问题:

class CustomUser(AbstractUser):
    # ...其他字段
    user_locked_with = models.ForeignKey(
        'self', 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True,
        related_name='locked_partner'
    )
    # ...其他字段

修改后测试中直接赋值用户对象即可:

user2 = User.objects.create_user(
    self.username2, self.email2, self.password2, 
    user_locked_with=user1
)
user1.user_locked_with = user2
user1.save()

视图中获取关联用户也更简洁:

user2 = user.user_locked_with
if not user2:
    return HttpResponseRedirect("/invalid-lock/")

总结

完全不需要重写AnonymousUser,只需通过测试登录用户+视图登录校验即可解决问题,可选优化字段关联类型能让逻辑更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:06:13