测试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
相关产品推荐
相关产品推荐

