iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0
自我挑戰組

月光下的Flask之旅系列 第 17

Day 17 Flask 靜態文件

  • 分享至 

  • xImage
  •  

這篇主要是講到靜態文件,靜態文件就是 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_folderstatic_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_folderstatic_url_path 這兩個參數的影響。若要使用到靜態文件的資源,有兩種方式:

  1. 直接找位置

    • 維持預設

      如果 static_folderstatic_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'>
      

    直接找位置的方式知道如何使用了吧!就是使用時必須抓位置路徑的最後一個名稱(我也不知道為什麼會這樣,但是不抓就不會動,改天有空我在看一下框架如何實作的吧)。

  2. url_for

    這個方式是 Flask 官方使用的寫法(前面只是我想跟你說可以這樣用而已),這個方式跟 static_folderstatic_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_folderstatic_url_path 都不會影響到 templates 取使用靜態文件,所以就讓我跳過它吧。

    而在 html 中要使用時,就要這樣使用:

    index.html

    <!-- 這個是 Flask 提供的方式, app.py 中不用設定這個 function -->
    <img src={{ url_for('static', filename='logo.svg' ) }} />
    

    推薦是使用 url_for() 這個方式,因為靜態文件改位置時不用到每個頁面再改一次,能夠在程式的維護上更加的方便。

那麼就大概這樣,基本上講這麼多只是要講最後一個方式而已,其他只是讓最後的方式能夠有個比較而已,話說本來這篇沒有要講這麼多的。

大家掰~掰~


上一篇
Day 16 Flask 前端
下一篇
Day 18 Flask 錯誤處理與回應
系列文
月光下的Flask之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言