Django访问/admin路径报404 移除static媒体路由后恢复原因咨询
问题根因
这个问题是Django三个核心运行逻辑叠加导致的,和配置不规范有直接关系:
- Django路由遵循严格顺序匹配规则:请求会按照
urlpatterns列表的从上到下顺序逐行匹配路由规则,只要命中第一个符合要求的规则,就立刻终止匹配交给对应视图处理,不会再校验后续路由。 - 你当前的
MEDIA_URL配置不符合规范,被设置成了根路径/(正常应该配置为/media/这类带独立前缀的路径)。这种情况下static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)会生成一个匹配全路径的通配路由^(?P<path>.*)$,而你用列表拼接的+操作,把这个通配路由放到了整个路由列表的最末尾。 - 你实际访问的路径是
/admin,末尾没有带斜杠,和你配置的前三个路由规则都不匹配:- 后台路由
admin/要求路径必须以斜杠结尾,匹配失败 - 首页路由
''仅匹配站点根路径/,匹配失败 - 文章详情路由
<slug:slug>/同样要求路径末尾带斜杠,匹配失败
- 后台路由
- 三个规则都没命中后,请求落到了最后那个static生成的通配路由上。这个路由没有末尾斜杠限制,直接把
admin作为路径参数传给静态文件服务视图,视图在媒体文件目录下找不到名为admin的资源,自然返回404错误。
移除static片段后问题消失,本质是触发了Django默认开启的APPEND_SLASH机制:只有当所有路由规则都匹配不上当前不带斜杠的请求时,Django才会自动给路径补末尾斜杠重新匹配,如果补斜杠后能命中路由,就返回301重定向到带斜杠的正确地址。通配路由存在时,不带斜杠的/admin已经被通配规则命中,哪怕视图返回404,Django也不会触发补斜杠重定向;移除通配路由后,/admin没有任何规则能匹配,Django才会自动补斜杠跳转到/admin/,正常命中后台路由。
正确修复方式
不要把MEDIA_URL设为根路径,修改配置为带独立前缀的形式即可:
MEDIA_URL = '/media/'
修改后static()生成的路由只会匹配/media/开头的媒体资源请求,不会生成全路径通配规则,既不影响正常业务路由、后台路由的匹配,也不会干扰APPEND_SLASH的自动重定向逻辑。
内容的提问来源于stack exchange,提问作者Snerd
相关产品推荐
相关产品推荐

