(以下内容参考众多资料,如有不当之处请大神指点,谢谢!)
环境:ubuntu16.04;django2.0
静态文件,是指像css,js,images之类的文件,在Django里面静态文件的处理与一般的视图是不一样的。想要真正明白静态文件处理机制,最好仔细阅读分析staticfiles相关源码(了解中)
(一)生产环境(一般指程序部署在nginx、Apache等Web服务器上)
静态文件交由Web服务器处理,Django本身不处理静态文件。简单的处理逻辑如下:
URI请求-----> 按照Web服务器里面的配置规则先处理
|---------->如果是静态文件,则由web服务器直接处理
|---------->如果不是则交由Django处理,Django根据urls.py里面的规则进行匹配
特别提示:在生产环境下,为了安全,务必要把setting.py文件中的DEBUG设置为False(DEBUG = False)。当DEBUG=False时,staticfiles将自动关闭(即django本身不再处理静态文件,更确切地说staticfiles以另一种方式运行)。
(二)开发环境(一般指程序部署在自带的Web服务器上)
特别提示:想要搞明白静态文件处理机制,最好搞明白staticfiles相关源码(了解中)。
在开发阶段,为了便于开发,我们一般使用自带的Web服务器,Django提供了在开发环境下对静态文件的处理机制(主要通过django.contrib.staticfiles实现)。
开发环境下,Django对静态文件的处理机制:
1、建议setting.py文件中DEBUG=True。这样,staticfiles才能正常发挥作用/开启
(如果不设置DEBUG=True可能会出错)。
2、建议setting.py文件中设置STATIC_URL,一般设置为STATIC_URL = '/static/'
。(如果不设置可能会出错:You're using the staticfiles app without having
set the required STATIC_URL setting或者html页面显示Server Error (500))。
3、在上述前提下,staticfiles自动地从STATICFILES_DIRS以及各个App的static
子目录里面搜索静态文件。
特别提示:当部署到生产环境时,需要在外部Web服务器的配置文件里面写好映射,这样/static将会被外部Web服务器处理,django.contrib.staticfiles虽然仍然存在,但因为不会接收到以/static/开始的路径,所以将不会产生作用。
推测:当DEBUG=True时,staticfiles自动地从STATICFILES_DIRS以及各个App的static子目录里面搜索静态文件;当DEBUG=False时,可以通过设置STATIC_ROOT和path(‘static/<path:path>’, serve, {‘document_root’: settings.STATIC_ROOT}),使得staticfiles从STATIC_ROOT目录里面搜索静态文件。
(一)STATIC_ROOT
STATIC_ROOT 是在部署静态文件时(pyhtonmanage.pycollectstatic)所有的静态文静聚合的目录,STATIC_ROOT要写成绝对地址,在这里,比如我的项目mysite是/home/mysite/
那么STATIC_ROOT 为 /home/mysite/collect_static/
当部署项目时,在终端输入:
python manage.py collectstatic
django会把所有的static文件(所有APP包括Admin下的静态文件和项目下的公共静态文件)都复制到STATIC_ROOT文件夹下。
(二)STATICFILES_DIRS
STATIC_ROOT 是在部署的时候才发挥作用, 而实际情况下,静态文件的一般安放位置有两种:
1.一种就是在每个app里面新建一个static文件夹,将静态文件放到里面,在加载静态文件时,比如要在模板中用到静态文件,django会自动在每个app里面搜索static文件夹(所以,不要把文件夹的名字写错哦, 否则django就找不到你的文件夹了)
2.另一种,就是在所有的app文件外面,建立一个公共的文件夹, 因为有些静态文件不是某个app独有的,那么就可以把它放到一个公共文件夹里面,方便管理(注意,建立一个公共的静态文件的文件夹只是一种易于管理的做法,但是不是必须的,app是可以跨app应用静态文件的,因为最后所有的静态文件都会在STATIC_ROOT里面存在)
那现在的问题是如何让django知道你把一些静态文件放到app以外的公共文件夹中呢,那就需要配置STATICFILES_DIRS了
STATICFILES_DIRS = (
os.path.join(BASE_DIR, ‘common_static’),
)
STATICFILES_DIRS告诉django,首先到STATICFILES_DIRS里面寻找静态文件,其次再到各个app的static文件夹里面找(注意, django查找静态文件是惰性查找,查找到第一个,就停止查找了)
(三)STATIC_URL
那么到此为止,静态文件的机制就可以运作了,但是有一个问题,我能不能通过url直接访问我在项目中的静态文件呢,答案肯定是啦,但是,注意,你是在浏览器是访问,你不可能输入你的静态文件的本地绝对地址吧,比如我的一种图片的本地地址为 /home/mysite/common_static/myapp/photo.png
那么别人不可能在浏览器上直接输入:
http://192.168.1.2:8000/home/mysite/common_static/myapp/photo.png
这样子,浏览器会报错, 没有该页面
那么django是如何让浏览器也可以访问服务器上的静态文件呢,前面已经说了,直接访问服务器本地的地址是不行的,那就需要一个映射,django利用STATIC_URL来让浏览器可以直接访问静态文件,比如:
STATIC_URL = ‘/static/’
那么可以在浏览器上输入:
http://192.168.1.2:8000/static/common_static/myapp/photo.png
那么就相当与访问/home/mysite/common_static/myap/photo.png
所以在浏览器上,利用前缀 STATIC_URL的具体内容,来映射STATIC_ROOT,
HTTP://192.168.1.2:8000/static 相当于 本地地址的STATIC_ROOT
一个小技巧:ctrl+shift+r 浏览器不使用缓存加载一个文件。