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

使用Django REST Framework POST数据时报404 Not Found如何解决?

解决Django REST Framework跨Docker主机POST请求404问题

问题描述

通过浏览器访问Django REST Framework的可浏览API时,/api/strategy/target/能正常显示对象列表及POST表单,且表单提交可成功创建数据;但使用Python requests库跨Docker主机发送POST请求时,服务器返回404 Not Found,日志记录显示请求路径未找到。服务器与客户端分别运行在不同Docker主机的容器中。


服务器端信息

控制台日志

django-1         | Not Found: /api/strategy/target/
django-1         | [26/Sep/2022 14:27:05] "POST /api/strategy/target/ HTTP/1.1" 404 23

项目URL配置(project/project/urls.py)

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("api/strategy/", include("strategy.urls")),
]

应用URL配置(strategy/urls.py)

from django.urls import path, include
from rest_framework import routers
from strategy.api.views import TargetViewSet


router = routers.DefaultRouter()
router.register("target", TargetViewSet, basename="targets-list")

urlpatterns = [
    path('', include(router.urls)),
]

视图代码(strategy/views.py)

from rest_framework import viewsets
from strategy.api.serializers import TargetSerializer
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAdminUser


# Create new model
@permission_classes([IsAdminUser])
class TargetViewSet(viewsets.ModelViewSet):
    serializer_class = TargetSerializer
    queryset = Target.objects.all()

客户端请求代码

res = requests.post("http://1.2.3.4:8001/api/strategy/target/",
                    data=data,
                    headers={'Authorization': 'Bearer {0}'.format(token)}
                    )

排查与解决方案

1. 确认URL斜杠一致性

Django默认开启APPEND_SLASH(默认值为True),浏览器访问时会自动补全URL末尾的斜杠并重定向,但requests不会自动处理该逻辑。可浏览API的表单提交会自动生成带斜杠的请求URL,但客户端代码若因拼写或其他原因发送了无斜杠的请求,会触发404。

  • 检查客户端代码中URL末尾是否明确包含/;
  • 确认Django项目settings.py中APPEND_SLASH = True,确保服务器能自动处理无斜杠的URL重定向。

2. 验证跨Docker主机的网络连通性

  • 确认服务器容器的8001端口已正确映射到宿主主机的8001端口,且宿主主机的防火墙、安全组已开放该端口的外部访问权限;
  • 在客户端主机执行curl http://1.2.3.4:8001/api/strategy/target/,验证是否能正常获取可浏览API页面,排除网络层面的连通问题。

3. 排查权限验证导致的隐性404

视图配置了IsAdminUser权限,若请求携带的token无效、过期,或对应的用户非管理员,DRF在部分场景下会返回404而非预期的403 Forbidden,以此隐藏敏感路由信息。

  • 打印客户端响应内容print(res.content),查看是否包含权限相关的提示信息;
  • 使用相同token在浏览器中提交可浏览API的POST表单,验证权限是否正常;
  • 在服务器端添加日志,打印请求头中的token及用户验证结果,排查权限校验流程。

4. 检查请求数据格式

DRF的ModelViewSet默认支持表单编码和JSON格式数据,但如果客户端发送的data格式不符合要求,可能导致路由匹配异常。

  • 尝试将请求改为发送JSON格式数据:
    import json
    res = requests.post(
        "http://1.2.3.4:8001/api/strategy/target/",
        data=json.dumps(data),
        headers={
            'Authorization': 'Bearer {0}'.format(token),
            'Content-Type': 'application/json'
        }
    )
    
  • 确认视图的parser_classes包含FormParser和MultiPartParser(ModelViewSet默认已包含,可显式指定排查)。

5. 修正路由注册的basename参数

DefaultRouter.register()方法中,手动指定的basename="targets-list"可能与默认生成的路由名称(target-list)冲突,导致路由匹配失败。

  • 移除basename参数,使用默认生成的路由名称:
    router.register("target", TargetViewSet)
    
  • 执行python manage.py show_urls命令,查看实际生成的路由规则,确认/api/strategy/target/对应POST方法的路由存在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:15:50