Django 中 static files 和 media files 有什么区别?生产环境如何处理?
简化版
static files 是项目自带的静态资源,如 CSS、JS、图片;media files 是用户上传内容,如头像、附件。生产环境通常用 collectstatic 收集静态文件交给 Nginx/CDN,用户上传文件则放对象存储或共享存储,不能混为一谈。
详细版
Django 开发环境可以帮你服务静态文件,但生产环境不推荐让 Django 直接扛静态资源。部署时运行:
python manage.py collectstatic
它会把各 app 和配置目录里的 static 文件收集到 STATIC_ROOT。用户上传文件由 MEDIA_ROOT/MEDIA_URL 或存储后端管理。面试重点是区分“代码随包发布的资源”和“运行时用户产生的文件”。
完整版教学
一、为什么要区分 static 和 media
静态文件随代码发布,版本可控;media 文件由用户上传,运行时不断变化。两者生命周期完全不同。
static: app.css, main.js, logo.png
media: avatar.jpg, resume.pdf, upload.xlsx
如果把用户上传文件放进代码目录,发布新版本或重建容器时可能丢失。
二、STATIC 配置怎么理解
STATIC_URL 是浏览器访问路径前缀,STATIC_ROOT 是 collectstatic 收集目标目录,STATICFILES_DIRS 是额外静态资源搜索目录。
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
collectstatic 会把资源集中到 STATIC_ROOT,方便 Nginx 或 CDN 服务。
三、MEDIA 配置怎么理解
MEDIA_URL 是用户上传文件访问前缀,MEDIA_ROOT 是本地存储路径。生产中更常见的是使用 S3、OSS、COS 等对象存储。
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
用户上传文件要考虑权限、大小限制、病毒扫描、私有访问和防盗链,不只是保存路径。
四、生产环境为什么不用 Django 服务静态文件
Django 是应用服务器,适合业务逻辑;静态资源适合由 Nginx、CDN 或对象存储提供。静态服务需要缓存、压缩、Range、并发下载,这不是 Django 的主场。
浏览器 -> CDN/Nginx -> static/media
浏览器 -> Django -> 动态接口
这样能减少应用 worker 压力。
五、容器部署的坑
容器文件系统通常是临时的。用户上传文件如果写在容器本地,容器重启、扩容或迁移后可能丢失。多副本部署时,用户上传到 A 容器,下一次请求打到 B 容器也可能找不到。
pod A: avatar.jpg
pod B: no avatar.jpg
所以 media 文件要用共享存储或对象存储。
六、缓存和版本化
静态文件可以加长缓存,但要配合文件名 hash,避免用户拿到旧资源。Django 生态里可以用 ManifestStaticFilesStorage 等方案。
app.css -> app.8f3a.css
media 文件通常不能简单永久缓存,因为用户可能替换头像或删除附件。
七、生产排查怎么说
如果线上静态文件 404,先看是否执行过 collectstatic,再看 Nginx/CDN 指向的目录是否是 STATIC_ROOT。如果用户上传文件 404,要检查存储后端、bucket 权限、MEDIA_URL、签名 URL 和对象是否真的存在。
static 404: collectstatic -> STATIC_ROOT -> Nginx/CDN
media 404: upload path -> storage backend -> permission/signature
这类问题不要只在 Django URL 里找原因,因为生产静态资源通常已经绕过 Django。
八、安全边界
media 文件还要防止用户上传可执行脚本、超大文件、恶意文件名和路径穿越。上传后通常要重命名、限制类型、限制大小,并把私有文件放到需要鉴权或签名访问的位置。
原始文件名: ../../a.py
存储文件名: uuid + safe extension
文件能上传成功,不代表能直接公开访问。
九、常见误区与追问
- 误区:static 和 media 都是图片文件,所以一样。 生命周期和来源不同。
- 误区:生产可以直接让 Django 返回静态文件。 不推荐,应交给 Nginx/CDN/对象存储。
- 误区:用户上传文件放容器本地没问题。 多副本和重启会丢失或不一致。
- 追问:collectstatic 做什么? 收集各处 static 到 STATIC_ROOT。
- 追问:用户头像属于 static 还是 media? media,因为它是用户上传内容。
- 追问:私有附件怎么保护? 不直接公开 URL,通过鉴权后签名下载或后端转发。
- 追问:静态文件缓存怎么破? 文件名 hash/versioning。
十、加强记忆
static 是“随代码来的资源”,media 是“用户运行时上传的文件”。static 用 collectstatic 交给 Nginx/CDN,media 用对象存储或共享存储并考虑权限。把生命周期讲清,这题就稳了。