Django加载根目录media资源报404的原因及自定义media模板标签实现
根目录media资源引用404的核心原因
所有404问题本质是路径匹配逻辑完全错位,和相对路径写得对不对没有关系:
- 浏览器解析相对路径的规则,是基于当前页面的HTTP访问地址计算资源请求URL,完全不感知模板文件在项目磁盘上的存放层级。不管你在模板里写
./media/image.png还是../../media/image.png,最终都是由浏览器拼出完整请求地址发给后端,不会按你本地的文件系统路径去解析。 - Django开发服务器默认只代理两类提前配置好的静态资源路径:
- 匹配
STATIC_URL前缀的请求,会去绑定的STATIC_ROOT目录下查找文件 - 匹配
MEDIA_URL前缀的请求,会去绑定的MEDIA_ROOT目录下查找文件
- 匹配
- 项目根目录下的
_media/文件夹,没有在settings.py中配置为MEDIA_ROOT对应的目录,也没有在URLconf里注册media资源的分发规则,后端收到/media/image.png的请求时,没有对应的路由能匹配到这个磁盘路径,自然返回404。 - 把media文件夹移到static目录下可以正常访问,是因为Django默认已经配置了
/static/前缀的资源代理规则,能直接定位到对应文件,和路径写法本身无关。
自定义media模板标签的实现方案
完全可以仿照内置static标签的逻辑实现自定义标签,完全避免手动拼接路径的问题:
- 在任意已注册的Django app下创建
templatetags目录,添加空的__init__.py文件将其标记为Python可导入包,新建media_tags.py的标签文件。 - 标签实现逻辑和内置static标签完全一致:
- 导入Django全局配置对象,读取
settings.py中预先定义的MEDIA_URL值 - 注册自定义模板标签,接收用户传入的资源相对路径,将其与
MEDIA_URL前缀拼接成完整的可访问URL返回
- 导入Django全局配置对象,读取
- 模板使用方式和内置标签无差异:在需要引用资源的模板头部加载自定义标签
{% load media_tags %},之后写{% media 'image.png' %}即可自动生成正确的资源路径,不需要手动计算相对层级、写死URL前缀。
前置配置提醒:实现完自定义标签后,只要在项目主URLconf中补充开发环境下的media资源路由分发规则,将
MEDIA_ROOT绑定到MEDIA_URL前缀下,就可以直接正常访问根目录media文件夹的资源,无需将资源文件移到static目录中。
内容的提问来源于stack exchange,提问作者CutePoison
相关产品推荐
相关产品推荐

