清水

最小的善行胜过最大善念

Django对静态文件的处理

本文 Django 版本:1.9.1

正如 Django 官方文档所说的,静态文件,像图片、CSS、JS 等都应该交由专门的服务器(如nginx)来处理,Django 只负责动态逻辑的处理。但在开发阶段也是要使用静态文件来调试页面,为此 Django 提供了一些工具来处理静态文件,作为开发阶段的临时解决方案。所以 Django 对静态文件的处理要分开发环境和生产环境两种情况来说明。

开发环境

Django 提供了 django.contrib.staticfiles 应用来处理静态文件,默认情况下在创建完项目后在 settings.py 里的 INSTALLED_APPS 配置项已包含了这个应用,同时设置了 STATIC_URL = '/static/' 这个配置,启用 staticfiles 应用后必须配置 STATIC_URL,那这配置是什么作用呢?

一般情况下,网页的静态文件是以如 <img src="/static/images/a.jpg" /> 的形式去引用。在 settings.py 里,当 DEBUG = True 时,Django 就利用 staticfiles 处理静态文件,假如 STATIC_URL 设置为 /static/,当收到URL为 /static/ 前缀开头的请求时,将首先通过 STATICFILES_FINDERS 设置的寻找方式去查找,STATICFILES_FINDERS 默认值为:

STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

第一种方式是 FileSystemFinder,文件系统查找方式,将按 STATICFILES_DIRS 的配置去查找,STATICFILES_DIRS 的默认值为[],STATICFILES_DIRS 的配置值要为绝对路径,如 STATICFILES_DIRS = ['/var/web/pcvc.net/static'],根据需要可直接在 settings.py 文件添加这个配置项。

第二种方式是 AppDirectoriesFinder,应用目录查找方式,也就是在每个应用下的 static 目录下查找,static 这个名称是固定的。

Django 会按照 STATICFILES_FINDERS 配置的顺序去查找,一旦找到资源就直接返回,不会再查找,所以如果存在多个应用且名字相同的资源文件要注意路径名称的问题。

Django 静态文件的查找基本上就是这样,还有另外一种是存储引擎方式,没有深入研究,不做介绍。

这时候就可以在模板文件里引用静态文件了,如 <img src="/static/images/a.jpg" />,当然,在 HTML 里直接用这种硬 URL 未免有点粗暴,一旦碰到文件目录发生改变,所有这样引用的模板文件都要改动到。官方推荐的是使用模板标签 static,如下:

模板文件里生成URL

其它方法可以查阅以下参考部分,这里就不再记录了。

生产环境

生产环境下主要是将静态资源统一收集到固定的路径,然后在 Web 服务器配置访问这个路径去访问所有静态资源,这时 Django 只是使用 collectstatic 将所有静态文件复制到 STATIC_ROOT 指定的绝对路径。

STATIC_ROOT = '/var/web/pcvc.net/collected_static',执行以下命令:

# python manage.py collectstatic

修改 nginx 网站的配置:

location /static {
    alias /var/web/pcvc.net/collected_static;
}

参考

Django对静态文件的处理——部署阶段
理解 django.contrib.staticfiles
Django中对静态文件的支持
Django中静态文件设置方法
Django处理静态文件方法