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

DRF router.register配置basename时user-detail单元测试404问题排查

问题背景

编写user-detail接口单元测试时遇到报错,最初怀疑问题出在response = self.client.get(reverse('user-detail',kwargs={'pk':1}))这行代码。路由通过router.register方式配置且已设置basename,编写测试用例时对路由反向解析逻辑存疑,无法定位错误位置。

测试用例代码

def test_list_user_detail(self):
    """
        查询用户详情
    """
    self.client.post(self.url, self.data, format='json')
    resp = self.client.post(
        '/auth/token/login/', data={'email': 'Foo@gmail.com', 'password': 'Boo'}, format='json')
    token = resp.data['auth_token']
    self.client.credentials(HTTP_AUTHORIZATION='token '+token)

    response = self.client.get(reverse('user-detail',kwargs={'pk':1}))
    print(response.data)
    self.assertEqual(response.status_code, status.HTTP_200_OK)

报错表现

测试运行后返回报错如下:

======================================================================
FAIL: test_list_user_detail (sellHouse.tests.UserTest)
List user detail
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\code\restfullapi\example\sellHouse\tests.py", line 68, in test_list_user_detail
    self.assertEqual(response.status_code, status.HTTP_200_OK)
AssertionError: 404 != 200

----------------------------------------------------------------------

打印response.data得到的返回内容为{'detail': ErrorDetail(string='Not found.', code='not_found')},接口返回404状态码,不符合预期的200状态码。

排查结论

这个404和路由反向解析没有关系。如果reverse()传入的路由名错误,会直接抛出NoReverseMatch异常,请求根本不会发出去。现在能拿到404响应,说明路由匹配已经成功,问题出在资源查询阶段,找不到pk=1对应的用户。
核心原因是硬编码pk=1传参:

  • Django运行单元测试时会创建独立的临时测试库,数据表主键计数不是固定从1开始,通过post请求创建的测试用户,主键值大概率不是1
  • 如果用户视图集自定义了lookup_field(比如用email、uid作为查询字段,没有用默认的pk字段),传pk=1也无法匹配到对应资源
修复方案
  • 接收创建用户接口的返回值,从响应数据中提取刚创建用户的真实主键,禁止硬编码pk值:
# 替换原代码中直接调用post不接返回值的写法
create_resp = self.client.post(self.url, self.data, format='json')
# 字段名和你用户序列化器返回的主键字段保持一致
user_pk = create_resp.data['id']

# 查询详情时传入真实主键
response = self.client.get(reverse('user-detail', kwargs={'pk': user_pk}))
  • 检查用户视图集的lookup_field配置,如果自定义了查询字段,反向解析传参时要把pk替换成实际配置的字段名。
  • 兜底排查:确认router.register配置的basename为user,如果basename设置为其他值(比如users),反向解析的路由名需要对应改成{basename}-detail格式。这类配置错误会直接抛出路由不存在异常,和当前404表现不符,不需要优先排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:39:54