staticfiles 應用程式

django.contrib.staticfiles 會將您每個應用程式(以及您指定的任何其他位置)的靜態檔案收集到一個單一位置,以便在生產環境中輕鬆提供。

另請參閱

有關靜態檔案應用程式的介紹和一些使用範例,請參閱如何管理靜態檔案(例如:圖片、JavaScript、CSS)。有關部署靜態檔案的指南,請參閱如何部署靜態檔案

設定

有關以下設定的詳細資訊,請參閱staticfiles 設定

管理指令

django.contrib.staticfiles 提供了三個管理指令。

collectstatic

django-admin collectstatic

將靜態檔案收集到 STATIC_ROOT

重複的檔案名稱預設會以類似範本解析的方式來處理:將使用在指定位置中第一個找到的檔案。如果您感到困惑,findstatic 指令可以協助您顯示找到哪些檔案。

在後續的 collectstatic 執行(如果 STATIC_ROOT 不是空的)中,只有當檔案的修改時間戳記大於 STATIC_ROOT 中檔案的時間戳記時才會複製檔案。因此,如果您從 INSTALLED_APPS 中移除應用程式,最好使用 collectstatic --clear 選項來移除過時的靜態檔案。

會使用 已啟用 的尋找器搜尋檔案。預設是查看 STATICFILES_DIRS 中定義的所有位置,以及 INSTALLED_APPS 設定所指定之應用程式的 'static' 目錄。

collectstatic 管理指令會在每次執行後呼叫來自 STORAGESstaticfiles 儲存後端的 post_process() 方法,並傳遞管理指令找到的路徑清單。它也會接收 collectstatic 的所有命令列選項。預設情況下,ManifestStaticFilesStorage 會使用它。

預設情況下,收集的檔案會從 FILE_UPLOAD_PERMISSIONS 接收權限,而收集的目錄會從 FILE_UPLOAD_DIRECTORY_PERMISSIONS 接收權限。如果您想要這些檔案和/或目錄有不同的權限,您可以子類化靜態檔案儲存類別,並分別指定 file_permissions_mode 和/或 directory_permissions_mode 參數。例如:

from django.contrib.staticfiles import storage


class MyStaticFilesStorage(storage.StaticFilesStorage):
    def __init__(self, *args, **kwargs):
        kwargs["file_permissions_mode"] = 0o640
        kwargs["directory_permissions_mode"] = 0o760
        super().__init__(*args, **kwargs)

然後將 STORAGES 設定中的 staticfiles 儲存後端設定為 'path.to.MyStaticFilesStorage'

一些常用的選項是:

--noinput, --no-input

不要提示使用者輸入任何內容。

--ignore PATTERN, -i PATTERN

忽略符合此 glob 樣式模式的檔案、目錄或路徑。使用多次以忽略更多。指定路徑時,即使在 Windows 上也始終使用正斜線。

--dry-run, -n

執行所有操作,但不修改檔案系統。

--clear, -c

在嘗試複製或連結原始檔案之前,清除現有的檔案。

為每個檔案建立符號連結,而不是複製。

--no-post-process

不要從 STORAGES 呼叫設定的 staticfiles 儲存後端的 post_process() 方法。

--no-default-ignore

不要忽略常見的私有 glob 樣式模式 'CVS''.*''*~'

如需完整選項清單,請執行以下命令來參考指令本身的說明:

$ python manage.py collectstatic --help
...\> py manage.py collectstatic --help

自訂忽略模式清單

預設的忽略模式清單 ['CVS', '.*', '*~'] 可以用比每次呼叫 collectstatic 時提供 --ignore 命令選項更持久的方式來自訂。提供自訂的 AppConfig 類別,覆寫此類別的 ignore_patterns 屬性,並在您的 INSTALLED_APPS 設定中將 'django.contrib.staticfiles' 替換為該類別路徑

from django.contrib.staticfiles.apps import StaticFilesConfig


class MyStaticFilesConfig(StaticFilesConfig):
    ignore_patterns = [...]  # your custom ignore list

findstatic

django-admin findstatic staticfile [staticfile ...]

使用啟用的尋找器搜尋一個或多個相對路徑。

例如:

$ python manage.py findstatic css/base.css admin/js/core.js
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
  /home/polls.com/src/django/contrib/admin/media/js/core.js
...\> py manage.py findstatic css\base.css admin\js\core.js
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
  /home/polls.com/src/django/contrib/admin/media/js/core.js
findstatic --first

預設情況下,會找到所有符合的位置。若要僅傳回每個相對路徑的第一個相符項,請使用 --first 選項

$ python manage.py findstatic css/base.css --first
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --first
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css

這是一個除錯輔助工具;它會準確顯示將為給定路徑收集哪些靜態檔案。

透過將 --verbosity 旗標設為 0,您可以抑制額外的輸出,只取得路徑名稱。

$ python manage.py findstatic css/base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css

另一方面,將 --verbosity 旗標設為 2,您可以取得所有被搜尋的目錄。

$ python manage.py findstatic css/base.css --verbosity 2
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Looking in the following locations:
  /home/special.polls.com/core/static
  /home/polls.com/core/static
  /some/other/path/static
...\> py manage.py findstatic css\base.css --verbosity 2
Found 'css/base.css' here:
  /home/special.polls.com/core/static/css/base.css
  /home/polls.com/core/static/css/base.css
Looking in the following locations:
  /home/special.polls.com/core/static
  /home/polls.com/core/static
  /some/other/path/static

runserver

django-admin runserver [addrport]

如果 staticfiles 應用程式已安裝,則覆寫核心 runserver 命令,並新增自動供應靜態檔案的功能。檔案供應不會透過 MIDDLEWARE 執行。

此命令會新增以下選項

--nostatic

使用 --nostatic 選項完全停用使用 staticfiles 應用程式供應靜態檔案。只有當 staticfiles 應用程式在您專案的 INSTALLED_APPS 設定中時,此選項才可用。

使用範例

$ django-admin runserver --nostatic
...\> django-admin runserver --nostatic
--insecure

使用 --insecure 選項強制使用 staticfiles 應用程式供應靜態檔案,即使 DEBUG 設定為 False。透過使用此選項,您承認此行為**極為低效**且可能**不安全**。這僅適用於本機開發,**絕不應在生產環境中使用**,且僅當 staticfiles 應用程式在您專案的 INSTALLED_APPS 設定中時才可用。

--insecure 不適用於 ManifestStaticFilesStorage

使用範例

$ django-admin runserver --insecure
...\> django-admin runserver --insecure

儲存空間

StaticFilesStorage

class storage.StaticFilesStorage

作為 FileSystemStorage 儲存後端的子類別,它使用 STATIC_ROOT 設定作為基礎檔案系統位置,並分別使用 STATIC_URL 設定作為基礎 URL。

storage.StaticFilesStorage.post_process(paths, **options)

如果此方法在儲存空間中定義,則會在每次執行後由 collectstatic 管理命令呼叫,並傳入找到的檔案的本地儲存空間和路徑(以字典形式),以及命令列選項。它會產生三個值的元組:original_path、processed_path、processed。路徑值是字串,而 processed 是一個布林值,表示是否已進行後處理,或者如果後處理失敗則表示例外。

ManifestStaticFilesStorage 在幕後使用此方法,以將路徑替換為其雜湊副本,並適當更新快取。

ManifestStaticFilesStorage

class storage.ManifestStaticFilesStorage

作為 StaticFilesStorage 儲存後端的子類別,它會透過將檔案內容的 MD5 雜湊附加到檔案名稱來儲存其處理的檔案名稱。例如,檔案 css/styles.css 也會儲存為 css/styles.55e7cbb9ba48.css

此儲存空間的目的是在某些頁面仍參照舊檔案時(例如,因為它們被您或協力廠商 Proxy 伺服器快取),繼續供應舊檔案。此外,如果您想將遠期過期標頭套用到已部署的檔案,以加速後續頁面瀏覽的載入時間,這也很有幫助。

儲存後端會自動將已儲存檔案中找到的路徑,與快取副本的路徑(使用 post_process() 方法)替換。用於尋找這些路徑的正規表示式(django.contrib.staticfiles.storage.HashedFilesMixin.patterns)涵蓋:

如果您想使用實驗性的正規表示式來涵蓋,請子類別化 ManifestStaticFilesStorage 並將 support_js_module_import_aggregation 屬性設定為 True

例如,內容如下的 'css/styles.css' 檔案:

@import url("../admin/css/base.css");

…將透過呼叫 ManifestStaticFilesStorage 儲存後端的 url() 方法來取代,最終儲存具有以下內容的 'css/styles.55e7cbb9ba48.css' 檔案:

@import url("../admin/css/base.27e20196a850.css");

在本地檔案中使用 integrity HTML 屬性

<script><link> 之類的標籤中使用可選的 integrity 屬性時,其值應根據所供應的檔案計算,而不是根據儲存在檔案系統中的檔案計算。這特別重要,因為根據靜態檔案的收集方式,其總和檢查碼可能會有所變更(例如,使用 collectstatic 時)。目前,沒有現成的工具可供使用。

您可以使用設定 manifest_storage 引數的自訂 ManifestStaticFilesStorage 子類別來變更資訊清單檔案的位置。例如:

from django.conf import settings
from django.contrib.staticfiles.storage import (
    ManifestStaticFilesStorage,
    StaticFilesStorage,
)


class MyManifestStaticFilesStorage(ManifestStaticFilesStorage):
    def __init__(self, *args, **kwargs):
        manifest_storage = StaticFilesStorage(location=settings.BASE_DIR)
        super().__init__(*args, manifest_storage=manifest_storage, **kwargs)

註解中的參照

ManifestStaticFilesStorage 不會忽略註解掉的語句中的路徑。這可能會在不存在的路徑上崩潰。您應該檢查並最終移除註解。

storage.ManifestStaticFilesStorage.manifest_hash

此屬性提供一個單一雜湊,當資訊清單中的檔案變更時,該雜湊就會變更。這對於向 SPA 傳達伺服器上的資產已變更(由於新的部署)非常有用。

storage.ManifestStaticFilesStorage.max_post_process_passes

由於靜態檔案可能會參照其他需要替換路徑的靜態檔案,因此可能需要多次替換路徑,直到檔案雜湊值收斂為止。為了防止因雜湊值無法收斂而導致無限迴圈(例如,如果 'foo.css' 參照 'bar.css',而 'bar.css' 又參照 'foo.css'),因此在放棄後處理之前,會設定最大處理次數。在參照數量較多的情況下,可能需要更高的處理次數。您可以透過繼承 ManifestStaticFilesStorage 並設定 max_post_process_passes 屬性來增加最大處理次數。預設值為 5。

要啟用 ManifestStaticFilesStorage,您必須確保滿足以下要求:

  • STORAGES 設定中,staticfiles 儲存後端設定為 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

  • DEBUG 設定設為 False

  • 您已使用 collectstatic 管理命令收集了所有靜態檔案

由於在執行期間建立 MD5 雜湊值可能會對您的網站造成效能負擔,staticfiles 會自動將所有已處理檔案的雜湊名稱對應關係儲存在名為 staticfiles.json 的檔案中。當您執行 collectstatic 管理命令時,會執行一次此操作。

storage.ManifestStaticFilesStorage.manifest_strict

如果在執行期間,staticfiles.json 資訊清單中找不到檔案,則會引發 ValueError。您可以透過繼承 ManifestStaticFilesStorage 並將 manifest_strict 屬性設定為 False 來停用此行為 – 不存在的路徑將保持不變。

由於需要執行 collectstatic,因此在執行測試時,通常不應使用此儲存方式,因為 collectstatic 不會作為正常測試設定的一部分執行。在測試期間,請確保 STORAGES 設定中的 staticfiles 儲存後端設定為其他值,例如 'django.contrib.staticfiles.storage.StaticFilesStorage'(預設值)。

storage.ManifestStaticFilesStorage.file_hash(name, content=None)

此方法用於建立檔案的雜湊名稱。需要針對給定的檔案名稱和內容傳回雜湊值。預設情況下,它會從內容區塊計算 MD5 雜湊值,如上所述。您可以自由覆寫此方法以使用您自己的雜湊演算法。

ManifestFilesMixin

class storage.ManifestFilesMixin

將此混合類別與自訂儲存空間一起使用,將檔案內容的 MD5 雜湊值附加到檔案名稱中,如 ManifestStaticFilesStorage 所做的那樣。

尋找器模組

staticfiles 尋找器有一個 searched_locations 屬性,它是一個目錄路徑清單,尋找器會在其中進行搜尋。用法範例:

from django.contrib.staticfiles import finders

result = finders.find("css/base.css")
searched_locations = finders.searched_locations

其他輔助工具

staticfiles 應用程式之外,還有一些其他輔助工具可用於處理靜態檔案:

靜態檔案開發檢視

靜態檔案工具主要用於協助將靜態檔案成功部署到生產環境中。這通常意味著需要一個單獨的、專用的靜態檔案伺服器,這在本地開發時需要處理很多額外負擔。因此,staticfiles 應用程式提供了一個**快速且簡陋的輔助檢視**,您可以使用它在開發時於本地提供檔案。

views.serve(request, path)

此檢視函數會在開發期間提供靜態檔案。

警告

只有在 DEBUGTrue 時,此檢視才會運作。

這是因為此檢視**效率極低**,而且可能**不安全**。這僅適用於本地開發,**絕不應在生產環境中使用**。

注意

為了猜測所提供檔案的內容類型,此檢視依賴於 Python 標準程式庫中的 mimetypes 模組,該模組本身依賴於底層平台的對應檔案。如果您發現此檢視未針對某些檔案傳回正確的內容類型,則很可能是平台的對應檔案不正確或需要更新。例如,可以透過在 Red Hat 發行版上安裝或更新 mailcap 套件、在 Debian 發行版上安裝 mime-support 套件,或者透過編輯 Windows 登錄中的 HKEY_CLASSES_ROOT 下的索引鍵來實現。

此檢視會由 runserver 自動啟用(且 DEBUG 設定設為 True)。若要搭配不同的本機開發伺服器使用此檢視,請將以下程式碼片段新增至主要 URL 設定的末尾:

from django.conf import settings
from django.contrib.staticfiles import views
from django.urls import re_path

if settings.DEBUG:
    urlpatterns += [
        re_path(r"^static/(?P<path>.*)$", views.serve),
    ]

請注意,模式的開頭 (r'^static/') 應為您的 STATIC_URL 設定。

由於這有點複雜,因此還有一個輔助函數可以為您執行此操作:

urls.staticfiles_urlpatterns()

這會傳回正確的 URL 模式,以將靜態檔案提供給您已定義的模式清單。像這樣使用它:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns

# ... the rest of your URLconf here ...

urlpatterns += staticfiles_urlpatterns()

這會檢查您的 STATIC_URL 設定,並連線檢視以相應地提供靜態檔案。請別忘了適當地設定 STATICFILES_DIRS 設定,以讓 django.contrib.staticfiles 知道除了應用程式目錄中的檔案之外,還要在哪裡尋找檔案。

警告

這個輔助函式只有在 DEBUG 設定為 True,且您的 STATIC_URL 設定既不是空的,也不是像 http://static.example.com/ 這樣的完整 URL 時才會運作。

這是因為此檢視**效率極低**,而且可能**不安全**。這僅適用於本地開發,**絕不應在生產環境中使用**。

支援「即時測試」的特殊測試案例

class testing.StaticLiveServerTestCase

這個 unittest TestCase 子類別繼承自 django.test.LiveServerTestCase

就像其父類別一樣,您可以使用它來編寫需要執行測試中的程式碼,並透過 HTTP 使用測試工具(例如 Selenium、PhantomJS 等)來使用它的測試,因此也需要發布靜態資源。

但考慮到它使用了上面描述的 django.contrib.staticfiles.views.serve() 視圖,它可以在測試執行時透明地覆蓋由 staticfiles 查找器提供的資源。這意味著您不需要在測試設定之前或作為測試設定的一部分執行 collectstatic

回到頂部