根本原因是STATIC_URL与STATICFILES_DIRS配置不匹配或开发服务器未启用静态文件服务;DEBUG=True且INSTALLED_APPS含'django.contrib.staticfiles'时,runserver才响应/static/请求。

直接结论:必须用 {% static %} 标签,且 STATIC_URL 和 STATICFILES_DIRS 配置不匹配是 404 的主因,不是路径写错。
为什么 {% static 'css/base.css' %} 渲染后 404?
Django 开发服务器只在 DEBUG=True 且 'django.contrib.staticfiles' 在 INSTALLED_APPS 中时,才响应 /static/... 请求。常见错误包括:
-
STATIC_URL写成'/static/'(开头带斜杠)→ 渲染出//static/css/base.css,浏览器拒绝请求 -
STATICFILES_DIRS用了相对路径或字符串拼接,比如os.path.join('static')→ Django 找不到真实目录 - 实际 CSS 文件没放在
STATICFILES_DIRS指向的目录下(例如你配了BASE_DIR / 'static',但文件却在myapp/static/css/里) -
DEBUG=False时,runserver默认不提供静态文件服务(生产环境应由 Nginx 处理)
模板里怎么写才对?
三件事缺一不可:
- 模板顶部必须有
{% load static %}(不能省,也不能写在<html>之后) -
href值必须是{% static 'css/base.css' %}这种形式——路径是相对于STATICFILES_DIRS下某个目录的子路径,**不加开头斜杠** - 不要手写
/static/css/base.css:它绕过 Django 静态文件机制,一旦你改了STATIC_URL就全挂
示例正确写法:
提供使用 django-unfold (v0.56+) 构建高级 Django 管理界面的专业指导。当用户提及 django-unfold、unfold admin 等内容时使用此技能。
立即学习“前端免费学习笔记(深入)”;
{% load static %}
<link rel="stylesheet" href="{% static 'css/base.css' %}">
如何动态切换主题 CSS?
{% static %} 只接受字面量字符串,不支持变量拼接,所以 {% static user.theme|add:'.css' %} 会报错或静默失败。
- 视图中提前构造好 URL:
context['theme_css'] = static(f'css/{user_preferred_theme}.css'),模板里直接{{ theme_css }} - 若主题来自 session 或 request,建议统一在 context processor 或中间件里注入,避免每个视图重复处理
- 多个主题可传列表:
context['themes'] = ['light', 'dark', 'blue'],模板中用{% for t in themes %}<link href="{% static 'css/'|add:t|add:'.css' %}">{% endfor %}—— 注意:这里add是过滤器,{% static %}仍只接收字面量,所以仍需确保每个'css/light.css'等路径真实存在
最容易被忽略的细节
路径分隔符和 BASE_DIR 写法决定成败。用 pathlib.Path 是最稳的:
-
STATICFILES_DIRS = [BASE_DIR / 'static']✅(自动处理/或\) -
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]❌(Windows 下可能出\,引发路径解析失败) -
STATIC_URL = 'static/'✅(结尾斜杠可选,但开头绝对不能有斜杠) - 确认
static/css/base.css文件真实存在于磁盘上,而不是只在 IDE 里“看起来有”

















