Django静态文件访问异常:仅static/路径返回404错误
这个问题的核心是Django开发模式下静态文件处理机制的冲突:
当
DEBUG=True时,django.contrib.staticfiles(默认已包含在INSTALLED_APPS中)会自动注册一个针对STATIC_URL路径的请求处理器。它的工作逻辑是从各个应用的static子目录、STATICFILES_DIRS配置的目录中查找静态文件,完全不会用到STATIC_ROOT(这个目录是生产环境下collectstatic命令收集所有静态文件的目标目录)。你手动在
urls.py中添加的static(settings.STATIC_URL, document_root=settings.STATIC_ROOT),是想让Django从STATIC_ROOT目录返回静态文件,但因为staticfiles的内置处理器优先级更高,当请求/static/style.css时,实际是由staticfiles来处理的——如果你的文件只放在STATIC_ROOT里,而不在staticfiles的查找路径中,就会返回404。当你把
STATIC_URL改成anything/这类非默认值时,staticfiles不会自动处理这个路径,请求会落到你手动添加的static()函数上,直接从STATIC_ROOT读取文件,所以能正常访问。
根据你的需求,有几种可选方案:
开发环境推荐方案:移除
urls.py中手动添加的static()代码块,依赖staticfiles的自动处理。把静态文件放到对应应用的static子目录下,或者在settings.py中配置STATICFILES_DIRS指定额外的静态文件目录,staticfiles会自动找到这些文件并返回。保留手动static()的方案:要么继续使用非
static/的STATIC_URL,要么从INSTALLED_APPS中移除django.contrib.staticfiles(但这样会失去自动查找多应用静态文件的便利)。适配生产环境的验证方案:如果想测试
STATIC_ROOT的效果,先执行python manage.py collectstatic命令,把所有静态文件收集到STATIC_ROOT目录中,此时即使保留staticfiles,它也会优先从STATIC_ROOT读取文件(不过开发环境一般不推荐这么做,会增加额外操作成本)。
内容的提问来源于stack exchange,提问作者Muhib Al Hasan

