這篇主要是講到靜態文件,靜態文件就是 CSS 、 JavaScript 與圖片檔之類的檔案(因為在 Flask 中 html 與這些東西位置不同,所以我沒講到 html,不然 html 應該也算靜態檔案)。而在 Flask 中要如何使用這些靜態檔案呢?位置又在哪裡呢?
再來說說要如何設定靜態文件,在 app.py
中一開始一定會有這行:
app = Flask(__name__)
在這行中,其實可以加入許多參數,而它原本的型態是長這樣的
Flask(import_name, static_url_path=None, static_folder='static', static_host=None, host_matching=False, subdomain_matching=False, template_folder='templates', instance_path=None, instance_relative_config=False, root_path=None)
除了 import_name 是必填的(基本上是填 __name__。可以改,但是這會扯到很多東西,所以算了),其他都是選填。這篇主要會講到的就是 static_folder
、 static_url_path
這兩個參數,因為這兩個設定完要使用的時候比較特殊一點。
其中 static_folder
就是靜態文件的位置,必須設定為指向存放靜態位置的地方(廢話),預設是存放在專案根目錄下的 static
(沒有 s
),前面不可為斜線開頭;後面可有可無。
那 static_url_path
又能做什麼呢,這個是將靜態位置的位置虛擬成一個假路徑,讓資源到假路徑去找(聽不太懂對吧,我已經用盡了我 2X 年的中文功力去形容了,如果還是不懂的話到使用時直接看範例吧),唯一要注意的是使用的時候前面必須為斜線開頭,後面可有可無。
而 template_folder
就是上一篇所講的前端頁面位置了,在使用時基本上不太會遇到問題,所以我快速講一下:如果頁面在 uvw/xyz/index.html
,這個參數設成這樣:
# 前面不可為斜線開頭,後面無所謂
app = Flask(__init__, template_folder='uvw/')
那回傳畫面就這樣寫就可以了。
@app.route('')
def index():
return render_template('xyz/index.html')
對,沒錯,就接著寫。接著來進入主題講一下靜態文件。
再來說說要如何使用靜態文件,在 Flask 中這些靜態文件使用方式會受到 static_folder
、 static_url_path
這兩個參數的影響。若要使用到靜態文件的資源,有兩種方式:
直接找位置
維持預設
如果 static_folder
跟 static_url_path
都不做設定,那麼在 html 就必須這樣呼叫:
index.html
<img src='static/logo.svg'>
設定 static_folder
如果現在設定了 static_folder
,架構像這樣(對啦,有點扯,只是舉例,看看就好):
ithome
├── abc
│ └── def
│ └── logo.svg
├── templates
│ ├── res
│ │ └── home.html
│ ├── base.html
│ └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
app.py
這樣設定:
# static_folder 前面不可為斜線開頭,不然會找不到;後面可有可無。
app = Flask(__init__, static_folder='abc/def/')
index.html
內要直接找位置就必須這樣寫:
<!-- 這個前面有沒有斜線沒關係 -->
<img src='def/logo.svg'>
好像有點抓到感覺了對吧,再看一個。
設定 static_url_path
如果現在設定了 static_url_path
(還記得它是虛擬出來的假路徑嗎,不用真的建立的位置喔), 那有沒有設定 static_folder
其實沒差(只要它還是正確的指向靜態文件的位置就好)。而架構一樣長這樣:
ithome
├── abc
│ └── def
│ └── logo.svg
├── templates
│ ├── res
│ │ └── home.html
│ ├── base.html
│ └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
app.py
這樣設定:
# static_folder 前面不可為斜線開頭,不然會找不到;後面可有可無。
# static_url_path 前面必須為斜線開頭;後面可有可無。
app = Flask(__init__, static_url_path='/img/',
static_folder='abc/def/')
那麼 index.html
內要直接找位置就必須這樣寫:
<!-- 這個前面有沒有斜線沒關係 -->
<img src='img/logo.svg'>
直接找位置的方式知道如何使用了吧!就是使用時必須抓位置路徑的最後一個名稱(我也不知道為什麼會這樣,但是不抓就不會動,改天有空我在看一下框架如何實作的吧)。
url_for
這個方式是 Flask 官方使用的寫法(前面只是我想跟你說可以這樣用而已),這個方式跟 static_folder
與 static_url_path
設定了什麼無關(也就是說改路徑了之後,可以不用跑到每個頁面再改一次了)。實作就延續上面的架構:
ithome
├── abc
│ └── def
│ └── logo.svg
├── templates
│ ├── res
│ │ └── home.html
│ ├── base.html
│ └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
app.py
中怎麼設 static_folder
與 static_url_path
都不會影響到 templates 取使用靜態文件,所以就讓我跳過它吧。
而在 html 中要使用時,就要這樣使用:
index.html
<!-- 這個是 Flask 提供的方式, app.py 中不用設定這個 function -->
<img src={{ url_for('static', filename='logo.svg' ) }} />
推薦是使用 url_for() 這個方式,因為靜態文件改位置時不用到每個頁面再改一次,能夠在程式的維護上更加的方便。
那麼就大概這樣,基本上講這麼多只是要講最後一個方式而已,其他只是讓最後的方式能夠有個比較而已,話說本來這篇沒有要講這麼多的。
大家掰~掰~