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

Django登录单元测试返回AnonymousUser,断言失败求助

Django登录单元测试失败排查求助

我写了一个Django登录功能的单元测试,但执行后一直失败,用户始终处于匿名状态,麻烦帮忙看看哪里出问题了!

我的单元测试代码

"""This is the unit test case for form element"""
from django.test import TestCase
from django.contrib.auth.models import User

class TestForm(TestCase):
    def setUp(self):
        self.credentials = {
            'username': 'abhishek',
            'password': 'Abhishek@12345'}
        User.objects.create_user(**self.credentials)

    def test_login(self):
        # send login data
        response = self.client.post('/accounts/login', self.credentials, follow=True)
        # should be logged in now
        print(response.context['user'])
        self.assertTrue(response.context['user'].is_authenticated)

执行测试的命令及错误输出

执行命令:

python ../manage.py test accounts.tests.test_form.TestForm

错误输出:

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
AnonymousUser
F
======================================================================
FAIL: test_login (accounts.tests.test_form.TestForm)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Django\webapplication\accounts\tests\test_form.py", line 18, in test_login
    self.assertTrue(response.context['user'].is_authenticated)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 1 test in 3.391s
FAILED (failures=1)
Destroying test database for alias 'default'...

登录视图代码(views.py)

from django.shortcuts import render, redirect, render_to_response
from django.contrib import auth
from accounts.forms import UserAttributeModelForm, UserModelForm
import logging  # 补充缺失的logging导入

LOG = logging.getLogger(__name__)

def login(request):
    """This is the function to Login authenticated user"""
    LOG.debug("Inside Login function")
    message = ""
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = auth.authenticate(username=username, password=password)
        if user is not None:
            # correct username and password login the user
            auth.login(request, user)
            return redirect("/crudapplication/show")
        else:
            message = "Error wrong username/password"
    return render(request, 'registration/login.html', {'message': message})

排查思路与解决方案

我帮你梳理几个核心问题点,逐一排查应该就能解决:

1. URL末尾斜杠缺失(最可能的原因)

Django默认开启APPEND_SLASH配置,当请求/accounts/login时,会自动重定向到带斜杠的/accounts/login/,但重定向过程中POST请求的数据会丢失,导致登录请求变成了空数据的GET请求,自然无法认证。

修改测试代码的请求URL:

response = self.client.post('/accounts/login/', self.credentials, follow=True)  # 加上末尾的斜杠

2. 验证密码匹配性

虽然User.objects.create_user会自动哈希密码,但可以在测试中添加验证步骤,排除密码不匹配的问题:

def test_login(self):
    user = User.objects.get(username='abhishek')
    print(user.check_password('Abhishek@12345'))  # 正常应该输出True
    # 后续登录逻辑...

3. 检查重定向后的上下文

使用follow=True后,response指向的是重定向后的/crudapplication/show页面。如果该页面的视图没有将用户信息传入上下文,或者不需要登录即可访问,就会出现匿名用户的情况。可以修改测试逻辑,直接验证客户端登录状态:

def test_login(self):
    # 先执行登录请求
    self.client.post('/accounts/login/', self.credentials)
    # 直接检查客户端是否已登录
    response = self.client.get('/crudapplication/show')
    self.assertTrue(response.context['user'].is_authenticated)

4. 修复视图的logging缺失

你的视图代码中使用了logging但未导入,会导致视图抛出异常中断登录流程,必须补上import logging语句。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:04:31