引言
這個(gè)問(wèn)題出在以Djiango做后臺(tái)的前端界面上脯燃。按以往的習(xí)慣,css蒙保,js辕棚,image等靜態(tài)文件直接在前端html中寫(xiě)好鏈接,直接丟上去就可以邓厕,但當(dāng)我把含外部css的html在丟到Django后發(fā)現(xiàn)逝嚎,css并沒(méi)有載入,自然详恼,其他靜態(tài)文件也是如此补君。
最初百度查找解決方案,但很多使用的版本與我的不同昧互,解決方案也有偏差赚哗,其他可用的方案也并沒(méi)有講清楚(其實(shí)就是我沒(méi)能理解)她紫,于是自己去看了文檔寫(xiě)下了自己的理解
相關(guān)軟件及版本:
Django 2.1.3
python 3.7.0
Django文檔管理靜態(tài)文件:
原因分析
出現(xiàn)這個(gè)問(wèn)題其實(shí)是因?yàn)槌绦騿T太想當(dāng)然了(但一般肯定會(huì)覺(jué)得直接丟上去沒(méi)問(wèn)題的啊混蛋)。在以往的php做后端的例子中屿储,我們只要知道url就可以訪問(wèn)網(wǎng)站根目錄下的任何文件贿讹。以外部css為例,在瀏覽器獲得html文件后會(huì)對(duì)資源進(jìn)行鏈接够掠,鏈接css文件時(shí)民褂,將向服務(wù)器請(qǐng)求css的url對(duì)應(yīng)的css文件,該css文件確實(shí)存在疯潭,于是服務(wù)器將之返回赊堪,瀏覽器成功鏈接到外部css文件。整個(gè)過(guò)程十分簡(jiǎn)單竖哩。
那么為什么Django鏈接不到哭廉?原因出在一開(kāi)始,css對(duì)應(yīng)的url不存在相叁。Django并不像php那樣可以訪問(wèn)網(wǎng)站根目錄下的文件遵绰,它只會(huì)對(duì)路由所包含的路徑進(jìn)行對(duì)應(yīng)的響應(yīng)。簡(jiǎn)單來(lái)說(shuō)增淹,你隨便往Django根目錄丟給文件椿访,在不編寫(xiě)路由的情況下,是不可能通過(guò)url獲得的虑润。同樣成玫,如果嘗試訪問(wèn)沒(méi)有寫(xiě)進(jìn)路由的css文件,那么返回只可能是404拳喻。既然資源404了哭当,那么瀏覽器請(qǐng)求不到,導(dǎo)入失敗就是理所當(dāng)然的冗澈。
解決方法
在settings.py中導(dǎo)入靜態(tài)資源
既然是url不存在钦勘,那么讓它存在就好。理論上只要把css對(duì)應(yīng)的url編寫(xiě)進(jìn)路由使其返回css文件渗柿,那么就能請(qǐng)求到了个盆。當(dāng)然我不會(huì)這么干脖岛,因?yàn)槎淦埽珼jango理所當(dāng)然地提供了解決方案。
在settings.py的INSTALLED_APPS重柴梆,我們可以找到django.contrib.staticfiles這項(xiàng)陨溅,它的作用就是管理靜態(tài)文件。它的功能大致可以理解為將settings.py中的STATICFILES_DIRS列表中的路徑變?yōu)榭稍L問(wèn)绍在。同時(shí)對(duì)于路徑门扇,django的settings.py中存在一個(gè)保存根路徑的變量:
BASE_DIRos.path.dirname(os.path.dirname(os.path.abspath(__file__)))
對(duì)于官方的解決方案雹有,靜態(tài)文件是保存在根目錄下的static文件夾中,所以使用一個(gè)變量指向static文件夾(當(dāng)然具體情況可以視實(shí)際路徑而更改):
STATIC_ROOT= os.path.join(BASE_DIR,'static')
然后臼寄,在settings.py中霸奕,存在這樣一個(gè)變量(如果沒(méi)有就自己加上吧):
STATIC_URL = '/static/'
這個(gè)變量的功能稍后再提。在這些準(zhǔn)備好之后吉拳,就可以將靜態(tài)文件路徑加到STATICFILES_DIRS列表中了质帅。比如,如果css文件相對(duì)static文件夾的路徑為“css/test.css”留攒,那么寫(xiě)入后:
STATICFILES_DIRS=[os.path.join(STATIC_ROOT,'css'),]
那么現(xiàn)在試著訪問(wèn)路徑(以本地端口127.0.0.1:8000為例):127.0.0.1:8000/static/css/test.css煤惩,會(huì)發(fā)現(xiàn)成功獲取。同樣炼邀,在html文件link時(shí)寫(xiě) href="static/css/test.css"魄揉,就可以成功獲得。
這里大概就能看出STATIC_URL的作用了拭宁。路徑中存在/static/這一部分洛退,和STATIC_URL有沒(méi)有關(guān)系呢?
嘗試這樣修改:
STATIC_URL = '/stardust/'
再訪問(wèn)127.0.0.1:8000/static/css/test.css红淡,返回404不狮。但改為訪問(wèn)127.0.0.1/stardust/css/test.css,訪問(wèn)成功在旱。確認(rèn)這個(gè)變量是靜態(tài)文件的url的目錄摇零。
我們?cè)賴L試將圖片文件添加進(jìn)去。比如在static文件夾下有一個(gè)src文件夾保存圖片等文件桶蝎,src/img文件夾保存圖片驻仅,其中有mio.jpg,于是如此修改:
STATICFILES_DIRS=[
os.path.join(STATIC_ROOT,'css'),
os.path.join(STATIC_ROOT,'src/img'),
]
訪問(wèn)127.0.0.1:8000/static/src/img/mio.jpg登渣,訪問(wèn)成功噪服。其他靜態(tài)資源添加方式也是如此,只用添加文件夾胜茧,就能訪問(wèn)內(nèi)部文件粘优。
值得多提的是,STATICFILES_DIRSSTATICFILES_DIRS支持添加二元元組呻顽,第一個(gè)值作為url中的路徑雹顺,第二個(gè)值作為實(shí)際路徑舉個(gè)例子,將它如此修改
STATICFILES_DIRS=[
('css',os.path.join(STATIC_ROOT,'css')),
('img',os.path.join(STATIC_ROOT,'src/img')),
]
127.0.0.1:8000/static/css/test.css依然訪問(wèn)成功廊遍,但是127.0.0.1:8000/static/src/img/mio.jpg訪問(wèn)失敗嬉愧。而訪問(wèn)127.0.0.1:8000/static/img/mio.jpg卻能成功。就是這樣喉前。
在上一步前提下使用html導(dǎo)入靜態(tài)資源
以css文件為例没酣,在上一步做到后王财,href屬性寫(xiě)為href="static/css/test.css"即可。不過(guò)django推薦的方案是使用模板導(dǎo)入裕便。對(duì)于模板我的理解并不太少所以只貼方案绒净。
現(xiàn)在文件前方使用{%load static %},之后在使用中(以同樣的css文件為例)如此寫(xiě):href="{%static '/css/main.css'%}"偿衰。這樣也可以成功訪問(wèn)疯溺。如下是官方文檔給出的關(guān)于圖片的例子:
{% load static %}
<img src="{% static "my_app/example.jpg" %}" alt="My image">
其他靜態(tài)資源也是如此。
至此哎垦,Django導(dǎo)入靜態(tài)文件的問(wèn)題得以解決囱嫩。本文講解有限,更多請(qǐng)查閱官方文檔漏设。