collectstatic 从哪里收集?同名文件怎么选?再次运行会重新复制吗?这篇建两个 app 加一个项目 assets 目录,把这些行为逐个试出来,顺便发现「同一秒内改的文件会被漏掉」这个细节。
6 static files copied to '<实验目录>', 2 skipped due to conflict. collected/ 下的文件: ['admin/override.txt', 'app1/a.css', 'app2/b.js', 'proj_only.js', 'shared.txt', 'site.css'] shared.txt 的内容: FROM PROJECT assets (STATICFILES_DIRS 里的先于 app 目录;app 之间按 INSTALLED_APPS 顺序) findstatic shared.txt -v2(所有候选位置): Found 'shared.txt' here: d88/assets/shared.txt d88/app1/static/shared.txt d88/app2/static/shared.txt Looking in the following locations: d88/assets
用 findstatic 文件名 -v2 可以查「某个静态文件到底来自哪里、还有哪些被遮蔽」。
无变化: 6 unmodified, 2 skipped due to conflict.
刚改完 site.css 立刻运行(与上次复制在同一秒内): 6 unmodified, 2 skipped due to conflict. | 目标里的内容: body{color:red}
等 1.2 秒后再改一次并运行: 5 unmodified, 2 skipped due to conflict. | 目标里的内容: body{color:green}
内容变了但 mtime 没变: 6 unmodified, 2 skipped due to conflict. | console.log(1) (collectstatic 用修改时间判断,内容变而 mtime 不变会漏掉)这个「同一秒内」的现象,我是在写脚本时无意中踩到的:改完文件立刻 collectstatic,发现没更新。真实部署里两次 collectstatic 通常隔得很久,但自动化测试脚本里会碰到。
--dry-run: 0 static files copied to '<实验目录>', 6 unmodified, 2 skipped due to conflict. 目标里多出来的旧文件 stale.txt(源里已不存在),不带 --clear 后: True (不会自动删除) --clear 之后 stale.txt 还在吗: False | 7 static files deleted, 6 static files copied to '<实验目录>', 2 skipped due to conflict. --link: 6 static files deleted, 6 static files symlinked to '<实验目录>', 2 skipped due to conflict. | site.css 是符号链接: True
部署脚本一般用 collectstatic --noinput --clear,避免旧文件累积(配合哈希文件名时,旧版本文件是否要保留给还在使用旧页面的客户端,是另一个取舍,第 89 篇)。
-i "*.js": [] (js 文件都被跳过) | 6 static files deleted, 4 static files copied to '<实验目录>', 2 skipped due to conflict. 没有 STATIC_ROOT: django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
开发时(runserver、DEBUG=True)静态文件直接从源目录提供,不需要 collectstatic。