在Django的setting.py中常见的三句静态资源(static)目录设置语句如下:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_list')] # 注意这是一个列表,即可以有多个目录的路径
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
STATIC_URL = '/static-url/'
本文介绍这三句话的作用。
要明白这三句话的作用,首先您要知道Django的HTML模板文件在引入静态文件,比如CSS、JS文件时,经过我实测 ,是不能直接写上绝对路径或相对路径来引用的。
比如下面这样直接写上绝对路径是不行的:
<link rel="stylesheet" href="E:/dj_project/app1/static/bootstrap-4.5.3-dist/css/bootstrap.css">
下面这样直接写上相对路径也是不行的:
<link rel="stylesheet" href="../static/bootstrap-4.5.3-dist/css/bootstrap.css">
当然下面这样写上相对路径也是不行的:
<link rel="stylesheet" href="/static/bootstrap-4.5.3-dist/css/bootstrap.css">
经实验证明,只有使用Django的相关模板标签才能在HTML模板文件中引用静态文件。
一个具体的例子如下:
{% load static %}
<!DOCTYPE html>
<html>
<head>
.......
<link rel="stylesheet" href="{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}">
</head>
......
</html>
即在模板文件的顶端使用语句{% load static %}
进行静态文件的加载,具体的加载点就在各个模板标签语句中,比如上面代码中的:{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}
静态文件的加载过程是下面这样的:
Step1 :
Django会对HTML模板中类似下面这样的模板标签进行解析,解析的结果是得到静态文件可能存在的部分路径:
"{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}
Step2:
按setting.py中的相关语句的设置并与Step1得到的部分路径组合得到完整路径,并按一定的顺序去遍历这些路径,从而找到需要的静态文件并进行加载。
接下来,以一个实际例子说明整个过程具体是怎么样的,把整个过程搞清楚了,本文开头提到的三条与静态资源目录设置的语句也就搞清楚作用了。
现在作如下这些假设:
①Django项目的根目录路径为:F:/dj_pro/,即BASE_DIR = 'F:/dj_pro/'
②应用的名字为app1
③模板HTML中有如下代码:
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>静态资源文件说明</title>
<link rel="stylesheet" href="{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}">
</head>
<body>
</body>
</html>
④setting.py中与静态资源目录设置的相关三条语句如下:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_list')] # 注意这是一个列表,即可以有多个目录的路径
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
STATIC_URL = '/static-url/'
现在当视图函数调用模板HTML文件后,遇到模板HTML的第1条语句:
{% load static %}
然后就去寻找模板HTML文件中与的相关模板标签,并找到了下面这一句:
{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}
这一句分为两部分,第一部分是模板变量static
,第二部分是路径常量bootstrap-4.5.3-dist/css/bootstrap.css
先说变量static
的作用:
变量static
的定义语句如下:
STATIC_URL = '/static-url/'
所以模板变量static
的具体值为:/static-url/,这个具体值与后面的路径常量bootstrap-4.5.3-dist/css/bootstrap.css
组成了一个URL,这个URL为:/static-url/bootstrap-4.5.3-dist/css/bootstrap.css
,那么这个URL有什么作用呢?
它的作用就是提供最终显示在浏览器的HTML页面的源代码中的相关字符串。比如网页在浏览器端成功打开后,我们用CTRL+U查看网页源代码,发现相关字符串的内容如下:
这就是这个URL的作用,当然也只是昊虹君的理解,如果昊虹君理解错误或者还有别的作用,麻烦这篇文章下评论告知一声,谢谢。
当然就这里来说,这个变量static
是没有作用的,但是如果是图片文件这些静态资源呢,那可能就用了,因为图片这类资源我们可以直接放在Nginx建立的网站的根目录下,并且通过配置Nginx配置这些图片的URL路径不进行反向代理。
接下来说第二部路径常量bootstrap-4.5.3-dist/css/bootstrap.css
的作用
常量bootstrap-4.5.3-dist/css/bootstrap.css
的作用要分两种情况来说明:
注意:不管是下面的哪两种情况,都与{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}
中的模板变量static
无关。
注意:不管是下面的哪两种情况,都与{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}
中的模板变量static
无关。
注意:不管是下面的哪两种情况,都与{% static 'bootstrap-4.5.3-dist/css/bootstrap.css' %}
中的模板变量static
无关。
第01种-没有执行命令python manage.py collectstatic
的情况
在这种情况下,Django在加载HTML模板文件时对于静态文件bootstrap.css的查找是按下面的顺序来进行的:
-
各个应用的
static
目录:
Django 会首先查找每个应用中的static
目录,这是默认的静态文件存放位置。每个应用通常都有一个static
目录,用于存放该应用的静态文件。如果你在应用中创建了这样的目录,Django 将会在其中查找相应的静态文件。
具体来说,由于我的应用名字为app1,所以会去查找由BASE_DIR/app1/static/
和bootstrap-4.5.3-dist/css/bootstrap.css
组成的路径。即路径:BASE_DIR/app1/static/bootstrap-4.5.3-dist/css/bootstrap.css,也就是路径:F:/dj_pro/app1/static/bootstrap-4.5.3-dist/css/bootstrap.css 中是否存在文件bootstrap.css。
如果找到了文件bootstrap.css,则停止查找,如果没有找到,继续往下找。 -
STATICFILES_DIRS
中的静态文件:
如果在各个应用的static
目录中找不到所需的静态文件,Django 将在STATICFILES_DIRS
指定的目录列表中进行查找。
具体来说,这里:STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_list')] # 注意这是一个列表,即可以有多个目录的路径
所以会到由 BASE_DIR/static_list/ 和 bootstrap-4.5.3-dist/css/bootstrap.css 组成的路径,即路径:
BASE_DIR/static_list/bootstrap-4.5.3-dist/css/bootstrap.css,也就是路径:F:/dj_pro/static_list/bootstrap-4.5.3-dist/css/bootstrap.css 中去查找文件bootstrap.css。
如果找到了文件bootstrap.css,则停止查找静态文件bootstrap.css。如果此时仍没有找到,则停止查找。
在第01种情况下,没有集中存放静态文件,而是直接在各个应用的 static
目录中和STATICFILES_DIRS指定的目录列表中查找。这在开发阶段是方便的,但在生产环境中通常会通过执行 python manage.py collectstatic
来将静态文件集中存放到一个目录,以提高性能和更好地组织静态文件,于是便产生了第2种情况。
第02种-执行命令python manage.py collectstatic
的情况
当运行 python manage.py collectstatic
命令时,Django 会从各个应用的 static
目录以及 STATICFILES_DIRS
指定的目录中收集静态文件,并将它们复制到 STATIC_ROOT
指定的目录下。这样做的目的是为了在生产环境中集中存放所有静态文件,以便于 Web 服务器更有效地提供它们。
这里要提问:Django在执行命令:python manage.py collectstatic 时,如果多个应用的static文件中包含了名字相同但内容不一样的css文件怎么办?
答:如果多个应用的static文件中包含了名字相同但内容不一样的CSS文件,collectstatic
默认情况下会根据应用的顺序覆盖早先的文件。这意味着在同一静态文件目录中,后面的应用的同名文件会覆盖前面应用的同名文件。
如果你想要保留所有同名文件,可以在每个应用的static
目录下创建子目录,将文件放置在这些子目录中。collectstatic
将会保持目录结构,因此同名文件不会相互覆盖。
例如:
myapp1/
static/
myapp1/
css/
style.css
myapp2/
static/
myapp2/
css/
style.css
在这种情况下,collectstatic
将会在静态文件目录中创建以下结构:
static_root/
myapp1/
css/
style.css
myapp2/
css/
style.css
这样做可以确保同名文件不会相互覆盖。
所以为了方便生产环境的部署,建议大家按上面的说明在应用目录的static下再建一个名称为应用名称的目录后,再放静态文件,这样避免在进行生产环境部署时产生麻烦。 当然如果你的整个django项目如果只有一个应用,那也不用这样,不过万一有一天你想增加应用呢?
好了,说回来。当执行命令 python manage.py collectstatic
后,Django在加载HTML模板文件时对于静态文件的查找则变成了下面的顺序来进行了(注意:此时与第1种情况的顺序有很大的区别了):
-
STATIC_ROOT
中的静态文件:
Django 会首先查找STATIC_ROOT
目录中是否存在所需的静态文件。这是因为STATIC_ROOT
是用于收集所有静态文件的根目录,它们都被复制到这个目录下。
具体来说,这里:STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
所以会去查找由 BASE_DIR/static_root/ 和 bootstrap-4.5.3-dist/css/bootstrap.css 组成的路径,即路径:BASE_DIR/static_root/bootstrap-4.5.3-dist/css/bootstrap.css,也就是路径 F:/dj_pro/static_root/bootstrap-4.5.3-dist/css/bootstrap.css。如果找到了文件bootstrap.css,则停止查找,如果没有找到,继续往下找。
-
STATICFILES_DIRS
中的静态文件:
如果在STATIC_ROOT
中找不到所需的静态文件,Django 将在STATICFILES_DIRS
指定的目录列表中进行查找。
具体来说,这里:STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_list')] # 注意这是一个列表,即可以有多个目录的路径
所以会到由 BASE_DIR/static_list/ 和 bootstrap-4.5.3-dist/css/bootstrap.css 组成的路径,即路径:
BASE_DIR/static_list/bootstrap-4.5.3-dist/css/bootstrap.css,也就是路径:F:/dj_pro/static_list/bootstrap-4.5.3-dist/css/bootstrap.css 中去查找文件bootstrap.css。
如果找到了文件bootstrap.css,则停止查找,如果没有找到,继续往下找。 -
各个应用的
static
目录:
如果在以上步骤中都找不到所需的静态文件,Django 将在各个应用的static
目录中查找。每个Django应用通常都有一个static
目录,用于存放该应用的静态文件。
具体来说,由于我的应用名字为app1,所以会去查找由BASE_DIR/app1/static/
和bootstrap-4.5.3-dist/css/bootstrap.css
组成的路径。即路径:BASE_DIR/app1/static/bootstrap-4.5.3-dist/css/bootstrap.css,也就是路径:F:/dj_pro/app1/static/bootstrap-4.5.3-dist/css/bootstrap.css 中是否存在文件bootstrap.css。
如果找到了文件bootstrap.css,则停止查找静态文件bootstrap.css。如果此时仍没有找到,则停止查找。
读懂了上面对具体过程的介绍下,相信大家也就知道了本文开头给出的三条语句的作用了,也知道了Django的HTML模板的静态文件查找和加载机制了。
一些补充和自己的心得:
①网上看到的,自己没试:如果要变量static
起作用,那么要加载应用 ‘django.contrib.staticfiles’,比如下面的配置代码:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app1', # 这是自己创建的应用,需要手动注册
]
应用 'django.contrib.staticfiles’在Django创建好项目时就默认添加的,自己不主动删除就没问题。
②如果静态文件不多、不大,个人感觉没必要执行语句 python manage.py collectstatic
③养成在各应用的static下再建一个名字为应用名字的文件夹后再放静态文件的习惯。