Django-2:django静态文件配置
Django静态文件配置
在第一章节中,我们简单介绍了django的基本操作,并且可以使用render、HttpResponse、redirect来呈现出一些粗糙的页面。
现在,如果在django项目中返回了一个html文件,该文件内部引入的CSS和JS文件又才存放在哪里呢?会不会访问不到呢?
2-3大章节为铺垫。
一、引子
本章节将通过案例,来详细介绍为什么要静态文件进行配置、配置之后可以实现什么效果,不配置又会有什么效果。
1.1 完成一个login页面
第一步:添加路由,以及对应视图函数
# urls.py
urlpatterns = [
'''略'''
url(r'^login/',views.login),
'''略'''
]
# views.py
def login(request):
return render(request,'login.html')
第二步:利用bootstrap,书写login页面
引入bootstrap有两种方式:
- 使用CDN。
- 将bootstrap的CSS和JS文件以本地形式存储
由于在实际项目中CDN有挂掉的可能从而影响到业务,所以往往都是采用本地存储。
在django项目中,CSS和JS或者其他框架、插件都是存放在项目根目录下的static目录 。
- 该文件不会自动生成,所以需要手动创建。
HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--..表示上一级目录-->
<link rel="stylesheet" href="../static/others/bootstrap.min.css">
<link rel="stylesheet" href="../static/others/bootstrap.js">
<link rel="stylesheet" href="../static/others/jquery-3.6.0.min.js">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-center">Login</h1>
<br>
<form class="form-horizontal" action="" method="post">
<div class="form-group">
<label for="ipt_uname" class="col-sm-2 control-label">Uname</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="ipt_uname" placeholder="Uname">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
1.1.1 附:项目文件结构
我们将html文件默认都放在templates文件夹下,将网站所使用的静态文件默认都放在static文件夹下。
这里由于使用的有jQuery和BootStrap框架,所以是在static的other目录。
2022-08-31
文档重新汇总会修改了很多地方,所以这里的路径和下列的代码可能有出处,后面代码静态文件将存放在各自的css和js文件夹中,不存在有others文件夹了。
![image-20210921180451640](https://s2.loli.net/2023/02/18/gWZsS2MAea7XDJO.png)
1.2 查看样式继承情况
直接打开:
- 写好的HTML页面直接在浏览器中打开,可以发现,BootStrap的样式生效,说明我们前端代码是没有问题的。
![image-20210921174056770](https://s2.loli.net/2023/02/18/TkEM3u4HW1it7qJ.png)
启动Django项目并访问接口:
- 通过Django进行访问,可以发现,在我们前端代码没问题的情况下,BootStrap的样式没有生效。
通过上述展示出的效果,我们发现通过django访问时,页面未继承bootstrap样式。
我们先通过F12–>网络,查看下css和js文件访问状态
![]()
全部都报404 not found,找不到该资源。
![]()
观察这里的请求网址,再仔细想想为什么我们访问http://127.0.0.1:8000/index/和http://127.0.0.1:8000/admin/ 就没有问题呢?
index和admin可以访问,是因为在urls文件中开设的有访问接口
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'index/',views.index), ]
总结:
- 我们在浏览器中输入url能够看到对应资源,是因为我们在后端中提前开设了该资源的接口,如果访问不到,说明后端没有开设该资源的接口。
- 所以,“静态文件配置”所要实现的目的就是,提供静态资源的访问接口。
二、静态文件配置
2.1 配置
作用:
-
为静态文件添加访问的接口
django知道我们会很频繁的使用静态资源,而每个资源都开设接口太费时间了。
所以可以通过在settings文件中进行配置,达到批量开设静态资源的效果。
以下为settings.py文件
# 略
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 略
STATIC_URL = '/static/'
# 以下为纯手写
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
'''
注:
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'),
os.path.join(BASE_DIR,'static1'),
os.path.join(BASE_DIR,'static2'),]
可以写多个路径,从上往下找,找不到就报错。
'''
先来看看效果:
![image-20210922170402322](https://s2.loli.net/2023/02/18/UVt6vpYFAbEMXW4.png)
此时我们可以看到,访问127.0.0.1/login页面已经没什么问题了,静态资源都成功的访问到了
2.2 静态文件配置详解
为什么只在settings.py中添加一个变量(值为列表,列表元素为路径)就可以实现访问得到静态资源呢?
配置文件代码
-
'''略''' BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # os.path.abspath(\_\_file\_\_)表示当前文件的绝对路径 # os.path.dirname()表示上级目录的路径 '''略''' STATIC_URL = '/static/' '''以下为纯手写''' STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static') ]
BASE_DIR:该变量为项目的绝对路径,比如:D:\路径\djangoProject
STATIC_URL:该变量为“令牌”,表示静态资源是以令牌值开头的,那么可以进入STATICFILES_DIRS列表的路径中进行查找。
STATICFILES_DIRS:该变量值为列表,里面存放着静态文件的查找路径。
类似于templates模板配置一样,利用路径拼接将templates文件夹添加到环境变量中。
静态文件配置,也同样是利用路径拼接,将static文件夹开放访问.
区分两个static的作用
STATIC_URL = '/static/' # 这里的static为"令牌"
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static') # 这里的static存放静态文件的文件夹
]
什么是“令牌”:
-
意思就是,如果想要访问静态文件,就必须以static开头。
<link rel="stylesheet" href="/static/others/bootstrap.min.css"> <link rel="stylesheet" href="/static/others/bootstrap.js"> <link rel="stylesheet" href="/static/others/jquery-3.6.0.min.js">
在HTML中,我们现在引入静态文件是以static开头,所以访问静态文件的链接也是以static开头,如下:
http://localhost:8000/static/js/jquery.min.js
http://localhost:8000/static/js/bootstrap.min.js
http://localhost:8000/static/css/bootstrap.css
正是因为我们的静态资源是以static开头的,所以可以进入STATICFILES_DIRS,在列表当中的所有路径下进行查找资源,没找到就报404。
当我们的静态资源不是以static开头,那么根本就不会到指定路径下进行资源查找。
验证
-
修改令牌
STATIC_URL = '/static_file/' # "令牌" STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static') ]
-
对应修改HTML代码
<script src="/static_file/js/jquery.min.js"></script> <script src="/static_file/js/bootstrap.min.js"></script> <link rel="stylesheet" href="/static_file/css/bootstrap.css">
-
查看静态资源的URL地址
http://localhost:8000/static_file/js/bootstrap.min.js
状态代码 200 OK
成功访问到静态资源。
总结:
-
修改了令牌之后,静态资源访问时就必须是以令牌开头,那么此时HTML文件中引入静态文件,就不能直接使用相对路径的方式引入了,因为令牌只要不是static,那么肯定访问不到。
-
''' 静态文件路径:/static/js/jquery-min.js 令牌名: static_file 那么前端HTML引入时的路径就等于 /static_file/js/jquery-min.js '''
流程:
- 当django发现访问路径是以static_file打头,且令牌也是static_file后,会在STATICFILES_DIRS列表中的所有路径下进行查找。
- 在列表的所有路径下,查找有没有js文件夹,再查询js文件夹中有没有一个叫jquery-min.js的文件。
- 如果有,那么成功访问,如果没有则资源访问失败。
2.3 动态解析
动态解析可以实现的效果:
- 不管令牌怎么改变,HTML文件在引入的时候都不收影响。
- 在没有配置的时候,settings中配置的令牌一改,那么所有HTML文件的所有link标签script标签的href属性和src属性都要进行变动。
格式:
-
<!--引入settings中的令牌--> {% load static %} <!--在引入静态文件的时候,用这个动态获取的令牌作为开头,后面路径补齐--> <link rel="stylesheet" href="{% static 'bootstrap.js' %}"> <script src="{% static 'bootstrap.js' %}"></script> <link rel="stylesheet" href="{% static 'bootstrap.min.css' %}">
固定格式,可以实时的获取STATIC_URL的值(令牌)到底是什么,是test,还是static,还是static_file。
相对于传统方式,该方法只在引入静态文件的时候需要按照模板语法的格式,之后不管令牌怎么更改,都不会影响静态资源的访问。
测试:
- 将令牌改为xxx
![image-20210922232446075](https://s2.loli.net/2023/02/18/JhpwgP2Ufvj3OIT.png)