DRF报错id期望数字但得空值 URL传id参数失效问题排查
问题原因与修复方案
这个报错的核心原因是视图接收到的id参数为空字符串,和你预期的数字4不符,90%以上的场景是请求路径配置错误导致没有匹配到目标路由,另外还有代码本身的隐藏bug,按以下顺序排查修复即可:
第一优先级排查:axios相对路径导致请求地址错误
你写的请求路径api/public/favourites/4/开头没有前导斜杠,属于相对路径,会基于当前前端页面的URL做拼接。如果当前页面不是域名根路径(比如在/thread/list/页面发起请求),实际请求地址会被拼成/thread/list/api/public/favourites/4/,这个地址无法匹配你配置的<int:id>格式路由,反而可能命中项目中其他带id参数的路由(比如DRF自动生成的路由规则),这类路由没有捕获到合法数字id时就会传入空字符串,抛出你看到的错误。
修复方式二选一即可:- 给请求路径加前导斜杠,写成根路径形式:
axiosInstance.post(`/api/public/favourites/4/`) - 给axios实例配置统一的baseURL,避免相对路径拼接问题:
const axiosInstance = axios.create({ baseURL: "http://127.0.0.1:8000/", // 本地开发替换为你的后端服务地址 // 其余配置项保留 })
验证方式:打开浏览器开发者工具的「网络」面板,找到这条POST请求,查看实际请求URL是否和你在
urls.py中配置的路由完全一致,没有多余的路径段。- 给请求路径加前导斜杠,写成根路径形式:
第二优先级排查:路由额外参数覆盖了捕获的id值
检查urls.py中的路由配置,不要在path的第三个位置传入和id同名的额外参数,这种写法会覆盖路径转换器捕获到的id值:# 错误写法:{'id':''}会强制把id参数设为空字符串 path('api/public/favourites/<int:id>/', add_favourites, {'id':''}, name='add_favourites'),如果存在这类配置,直接删掉额外传入的id参数即可,
<int:id>路径转换器会自动从URL中提取数字类型的id传给视图。必须修复的代码隐藏bug(路径问题解决后会触发)
你当前的视图逻辑还有两个会导致500错误的问题,需要一并修改:- 多对多字段操作类型错误:如果
thread.liked是关联User模型的多对多字段,add()/remove()方法需要传入User模型实例,不能传入username字符串,否则会触发类型错误;判断用户是否已收藏时,用用户id匹配效率更高。 - 视图缺少返回值:Django视图必须返回
HttpResponse类的响应对象,处理完逻辑后不能无返回值。
修复后的完整视图代码参考:
@csrf_exempt def add_favourites(request, id, *args, **kwargs): thread = get_object_or_404(Thread, id=id) if request.method == 'POST': # 未登录用户直接返回错误 if not request.user.is_authenticated: return JsonResponse({'code':403, 'msg':'请先登录'}, status=403) # 用用户id判断是否已收藏,直接操作用户实例 if thread.liked.filter(id=request.user.id).exists(): thread.liked.remove(request.user) is_fav = False else: thread.liked.add(request.user) is_fav = True # 返回操作结果 return JsonResponse({'code':200, 'msg':'操作成功', 'is_favourite': is_fav}) return JsonResponse({'code':405, 'msg':'请求方法不允许'}, status=405)- 多对多字段操作类型错误:如果
内容的提问来源于stack exchange,提问作者David Ho
相关产品推荐
相关产品推荐

