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

Django tests.py中如何为已认证用户发送带Token认证的POST请求?

问题核心原因
  1. 用户创建逻辑错误:直接使用User.objects.create存储明文密码,未经过Django认证体系要求的哈希加密,所有密码校验都会失败
  2. 认证逻辑不匹配:你使用DRF的Token认证,而Django原生测试客户端的login()/force_login()仅适配Session认证,Token认证不会读取session中的用户信息,所以即使确认session内有登录记录,接口依然返回403
  3. 获取Token的参数错误:请求/api-token-auth时传入的self.user1.password是数据库存储的哈希后的值,不是原始明文密码,自然校验失败
  4. 响应打印逻辑错误:DRF返回的Response对象没有context属性,所以打印结果为None,查看响应内容应该用response.json()或response.content
修复步骤

第一步:修复用户创建逻辑

改用create_user方法,Django会自动对密码做哈希处理,同时提前为测试用户生成Token:

class TodoTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        # 改用create_user自动加密密码
        cls.user1 = User.objects.create_user(
            username="xxxxx",
            email="xxxxx@gmail.com",
            password="password123",
        )
        # 手动为用户生成DRF Token(如果没有配置全局自动生成Token的信号,这一步必须加)
        from rest_framework.authtoken.models import Token
        cls.user1_token = Token.objects.create(user=cls.user1)

第二步:选择适配Token认证的测试方案

方案1:模拟真实请求携带Token头(最贴近实际使用场景)

def test_post_new_task_authorized_user(self):
    data = {
        "title": "A new post",
        "description": "Description of post",
        "responsible_username": "xxxxx",
    }
    # 请求头加入Token认证信息
    response = self.client.post(
        reverse("CUDtasks"), 
        data, 
        content_type="application/json",
        HTTP_AUTHORIZATION=f"Token {self.user1_token.key}"
    )
    # 打印响应内容用json()
    print("响应内容:", response.json())
    self.assertEqual(response.status_code, 200)

方案2:使用DRF专属测试客户端简化流程(单元测试更高效)

直接用force_authenticate绕过认证流程,不需要处理Token:

# 导入DRF的测试客户端
from rest_framework.test import APIClient

class TodoTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        # 这里和上面的修复后的用户创建逻辑一致
        cls.user1 = User.objects.create_user(
            username="xxxxx",
            email="xxxxx@gmail.com",
            password="password123",
        )

    def setUp(self):
        # 替换原生Client为APIClient
        self.client = APIClient()
        # 直接强制认证当前用户
        self.client.force_authenticate(user=self.user1)
    
    def test_post_new_task_authorized_user(self):
        data = {
            "title": "A new post",
            "description": "Description of post",
            "responsible_username": "xxxxx",
        }
        # format参数自动处理json编码,不需要手动指定content_type
        response = self.client.post(reverse("CUDtasks"), data, format="json")
        self.assertEqual(response.status_code, 200)

可选:修复获取Token的测试逻辑

如果需要测试Token获取接口,把传入的密码改为原始明文即可:

response = self.client.post(
    "/api-token-auth",
    {"username": self.user1.username, "password": "password123"}, # 传入明文密码
    content_type="application/json",
)
print(f"返回的Token: {response.json()}")
self.assertEqual(response.status_code, 200)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:09:02