共用方式為


教學課程:在 Visual Studio 中使用 Django 提供靜態檔案和範本繼承

本文介紹教學課程系列 〈在 Visual Studio 中使用 Django 網頁框架〉的步驟 3

本教學課程系列中的上一個步驟會建立具有獨立 HTML 單一頁面的最小 Django 應用程式。 新式 Web 應用程式通常由許多頁面組成,並使用 CSS 和 JavaScript 檔案等共用資源來提供一致的樣式和行為。 在步驟 3 中,您會使用 Visual Studio 專案範本,將內容新增至 Django 專案,並展開應用程式的功能。

在教學課程的步驟 3 中,您將瞭解如何:

  • 使用 Visual Studio 專案範本快速新增具有重複使用程式代碼的新檔案
  • 從 Django 程式代碼提供靜態檔案
  • 將更多頁面新增至 Django 應用程式
  • 使用範本繼承來建立頁首和跨頁面導覽

先決條件

在 Visual Studio 中探索專案範本

當您開發 Django 應用程式時,通常會新增更多 Python、HTML、CSS 和 JavaScript 檔案。 針對每個文件類型(以及您可能需要部署的 web.config 等其他檔案),Visual Studio 提供方便的 項目模板, 以幫助您入門。 您可以使用這些範本,透過重複使用程式代碼快速新增不同類型的新檔案。

  1. 若要檢視可用的範本,請移至 Visual Studio 中的 [方案總管],然後開啟項目結構。

  2. 在您要建立新檔案的資料夾上按下滑鼠右鍵,然後選取 [[新增>新項目][新增專案] 對話框隨即開啟:

  3. 若要使用模板,請選擇所需的模板、輸入檔案的名稱,然後選擇 新增

Visual Studio 會將檔案新增至您目前的專案,並標記原始檔控制的變更。

瞭解 Visual Studio 如何識別項目範本

Visual Studio 專案檔 (.pyproj) 包含專案類型標識符,將檔案標示為 Python 專案。 Visual Studio 會使用此類型識別碼來辨識並只顯示適合專案類型的專案範本。 Visual Studio 會遵循這種方法,為許多項目類型提供一組豐富的項目範本,而不需要每次都要求您排序它們。

從您的應用程式提供靜態檔案

在以 Python 建置的 Web 應用程式中(使用任何架構),您的 Python 檔案一律會在 Web 主機的伺服器上執行,且永遠不會傳送至使用者的電腦。 CSS 和 JavaScript 等其他檔案只會由瀏覽器使用,因此主機伺服器只會在要求它們時 as-is 傳遞它們。 這些類型的檔案稱為「靜態」檔案,Django 可以自動傳遞它們,而您不需要撰寫任何程序代碼。

Django 專案預設會設定為從應用程式 靜態 資料夾提供靜態檔案。 Django 專案的 settings.py 檔案中的下列程式代碼可以達成此行為:

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/

STATIC_URL = '/static/'

STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['static']))

您可以使用您想要的任何資料夾結構,組織應用程式 靜態 資料夾中的檔案,並使用 靜態 資料夾中的相對路徑來參考檔案。

在 HTML 範本中使用靜態 CSS 檔案

請遵循下列步驟將 CSS 檔案新增至應用程式,然後在 index.html 範本中使用 CSS 樣式表單:

  1. [方案總管]中,以滑鼠右鍵按兩下專案中 HelloDjangoApp 資料夾,選取 [新增>新增資料夾],並將資料夾命名 為靜態

  2. 以滑鼠右鍵點選 [靜態] 資料夾,然後選取 [新增>新項目]

  3. 在 [新增專案] 對話框中,選取 樣式表單 範本,將檔案命名為 site.cs,然後選取 [[新增]。

    Visual Studio 會將 site.css 檔案新增至專案,並在編輯器中開啟檔案。 以下是已更新 Django 專案結構的範例:

    顯示方案總管中靜態檔案結構的螢幕快照。

  4. 以下列樣式取代 site.css 檔案的內容:

    .message {
        font-weight: 600;
        color: blue;
    }
    
  5. 以下列標記取代 HelloDjangoApp/templates/index.html 檔案的內容:

    <html>
       <head>
          <title>{{ title }}</title>
          {% load static %} <!-- Instruct Django to load static files -->
          <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
       </head>
       <body>
          <span class="message">{{ message }}</span>{{ content }}
       </body>
    </html>
    

    此程式碼將教學課程系列步驟 2 中的 <strong> HTML 元素替換為引用 message 樣式類別的 <span> 元素。 以這種方式使用樣式類別可讓您更有彈性地設定 HTML 元素的樣式。

  6. 選取 [檔案]>[全部儲存]或使用 ctrl+Shift+S 鍵盤快捷方式,以儲存項目變更。 (此步驟並非必要,因為當您開發專案時,Visual Studio 會自動儲存您的檔案。

  7. 執行項目並觀察結果。 完成時,請停止應用程式。

  8. (選擇性)您可以將變更提交至原始碼控制,並更新遠端存放庫。 如需詳細資訊,請參閱本教學課程系列步驟 2 中的 提交至版本控制的變更

使用 {% 載入靜態 %} 標籤

{% load static %} 語句必須存在於 index.html 檔案中,以便在 HTML 元素(例如 <head><body>)中使用網站相對參考到靜態檔案。 在本節所示的範例中,「靜態檔案」是指自定義 Django 範本標記集。 標記集可讓您使用 {% static %} 語法來參考靜態檔案。 如果沒有 {% load static %} 標籤,您就會在應用程式執行時看到例外狀況。

新增不含 {% 載入靜態 %} 標籤的參考

您也可以在沒有使用 {% load static %} 標記的情況下,設定 HTML 標記中靜態檔案的網站相對路徑。 在此情況下,您會指定 Django 專案資料夾階層內 靜態 資料夾的位置:

<html>
    <head>
        <title>{{ title }}</title>
        <link rel="stylesheet" type="text/css" href="../../static/site.css" />
    </head>
    <body>
        <span class="message">{{ message }}</span>{{ content }}
    </body>
</html>

組織靜態檔案和資料夾

您可以根據您的專案需求,在 靜態 資料夾中新增其他 CSS、JavaScript 和 HTML 檔案。 組織靜態檔案的一般方法是建立名為 字型的子資料夾,腳本,以及 內容(適用於樣式表單和其他任何檔案)。 在每種情況下,請記得將資料夾納入 {% static %} 參考的相對路徑中。

將頁面新增至 Django 應用程式

將另一個頁面新增至 Django 應用程式牽涉到下列工作:

  • 新增定義檢視的 Python 函式
  • 新增頁面 HTML 標記的範本
  • 更新 Django 專案 urls.py 檔案中的 URL 路由

請遵循下列步驟,將 About (/about) 頁面新增至 HelloDjangoApp 專案,並從首頁連結至該頁面:

  1. [方案總管]中,右鍵點擊專案中的 templates/HelloDjangoApp 資料夾,然後選取 [新增>新項目]

    提示

    如果您沒有在 [新增 ] 功能表上看到 [新專案] 命令,請務必視需要停止 Django 應用程式,讓 Visual Studio 結束偵錯模式。

  2. 在 [新增專案] 對話框中,選取 HTML 頁面 範本,將檔案命名為 about.html,然後選取 [[新增]。

  3. 使用下列 HTML 標記取代 about.html 檔案的內容:

    <html>
       <head>
          <title>{{ title }}</title>
          {% load static %}
          <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
       </head>
       <body>
          <div><a href="home">Home</a></div>
          {{ content }}
       </body>
    </html>
    

    在後續步驟中,您會將首頁的明確連結取代為導覽列。

  4. HelloDjangoApp/views.py 檔案中,新增名為 about 的函式,以使用範本:

    def about(request):
       return render(
          request,
          "HelloDjangoApp/about.html",
          {
             'title' : "About HelloDjangoApp",
             'content' : "Example app page for Django."
          }
       )
    
  5. 在 Django 專案的 BasicProject/urls.py 檔案中,將 [about] 頁面的路徑新增為 urlPatterns 陣列中的最後一個專案:

    # Django processes URL patterns in the order they appear in the array
    urlpatterns = [
       re_path(r'^$', HelloDjangoApp.views.index, name='index'),
       re_path(r'^home$', HelloDjangoApp.views.index, name='home'),
       re_path(r'^about$', HelloDjangoApp.views.about, name='about')
     ]
    
  6. templates/HelloDjangoApp/index.html 檔案中,將下列標記新增為 <body> 元素中的第一個語句:

    <div><a href="about">About</a></div>
    

    此標記會新增 Django 應用程式 /about 頁面的連結。 在稍後的步驟中,您會將此連結取代為導覽列。

  7. 儲存您的項目變更,然後再次執行專案。 前往 /about 頁面,並檢查應用程式各頁面之間的導覽功能。

  8. 完成時,請停止應用程式。

路由至 「索引」頁面

如果您嘗試瀏覽至執行中應用程式的 /index 頁面,您會看到找不到 頁面(404) 錯誤。

雖然 HelloDjangoApp/views.py 檔案具有名為 index的函式,但是 Django 專案的 BasicProject/urls.py 檔案中的 URL 路由模式不包含符合字串 index的正則表達式。 應用程式「索引」頁面的當前表示式為 ^$。 若要比對字串 index,您必須為模式新增另一個URL項目 ^index$

下一節將描述為什麼在頁面範本中使用 {% url '<pattern_name>' %} 標記來參考模式 名稱 是更好的選擇。 在此情況下,Django 會為您建立適當的URL。 例如,您可以將 templates/HelloDjangoApp/about.html 檔案中的 <div><a href="home">Home</a></div> 標記取代為標記 <div><a href="{% url 'index' %}">Home</a></div>'index' 字串的使用現在可運作,因為 urls.py 檔案中的第一個URL模式會命名為 'index'。 您也可以使用 'home' 來參考第二個模式。

針對頁首和導覽使用範本繼承

許多 Web 應用程式都不是在每個頁面上使用明確的導覽連結,而是有商標標頭和導覽列,提供最重要的頁面連結、彈出式選單等等。 為了確保應用程式內的一致性,標頭和導覽列在所有頁面上都應該相同,但您不需要在每個頁面範本中重複相同的程序代碼。 您可以在單一檔案中定義所有頁面的通用部分。

Django 的範本化系統提供兩種方式,可跨多個範本重複使用特定元素:

  • 包含 是您在參考範本中以語法 {% include <template_path> %}插入特定位置的其他頁面範本。 如果您想要在程式代碼中動態變更路徑,也可以使用 變數。 在頁面主體中,通常會使用 Include,在頁面上的特定位置提取共用範本。

  • 繼承 使用頁面範本開頭的 {% extends <template_path> %} 語法來指定參考範本所建置的共用基底範本。 繼承通常用來定義應用程式頁面的共用配置、導覽列和其他結構。 此方法要求參考模板,以便僅在稱為 區塊的基礎模板中特定的區域進行新增或修改。

對於這兩種方法,<template_path> 值是相對於應用程式 範本 資料夾(也允許.././)。

基底範本會使用 {% block <block_name> %}{% endblock %} 標記來描述區塊。 如果參考範本使用具有相同區塊名稱的標籤,則參考範本中的區塊內容會覆寫基底範本中的相符區塊。

下列步驟示範範本繼承:

  1. [方案總管]中,以滑鼠右鍵按兩下 templates/HelloDjangoApp 資料夾,然後從名稱為 layout.htmlHTML 頁面 範本建立新檔案。

  2. 使用下列 HTML 標記取代 layout.html 檔案的內容:

    <!DOCTYPE html>
    <html>
    <head>
       <meta charset="utf-8" />
       <title>{{ title }}</title>
       {% load static %}
       <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
    </head>
    
    <body>
       <div class="navbar">
          <a href="/" class="navbar-brand">Hello Django</a>
          <a href="{% url 'home' %}" class="navbar-item">Home</a>
          <a href="{% url 'about' %}" class="navbar-item">About</a>
       </div>
    
       <div class="body-content">
          {% block content %}
          {% endblock %}
          <hr/>
          <footer>
             <p>&copy; 2024</p>
          </footer>
       </div>
    </body>
    </html>
    

    此範本包含一個名為 content的區塊,用於識別需要替換的所有內容,這些內容是參考頁面所需的。

  3. HelloDjangoApp/static/site.css 檔案中,將下列樣式新增至檔案結尾:

    .navbar {
       background-color: lightslategray;
       font-size: 1em;
       font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
       color: white;
       padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
       text-decoration: none;
       color: inherit;
    }
    
    .navbar-brand {
       font-size: 1.2em;
       font-weight: 600;
    }
    
    .navbar-item {
       font-variant: small-caps;
       margin-left: 30px;
    }
    
    .body-content {
       padding: 5px;
       font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    

    這些樣式定義會產生此練習的有趣結果。 本逐步解說不會示範回應式設計。

  4. 使用下列程式代碼取代 templates/HelloDjangoApp/index.html 檔案的內容:

    {% extends "HelloDjangoApp/layout.html" %}
    {% block content %}
    <span class="message">{{ message }}</span>{{ content }}
    {% endblock %}
    

    index 範本現在引用基礎範本,並覆寫 content 區塊。 您可以看到,使用繼承可簡化此範本。

  5. 使用下列程式代碼取代 templates/HelloDjangoApp/about.html 檔案的內容,因此 about 範本也會參考基底範本並覆寫 content 區塊:

    {% extends "HelloDjangoApp/layout.html" %}
    {% block content %}
    {{ content }}
    {% endblock %}
    
  6. 再次執行應用程式並觀察結果。 使用導覽列連結在應用程式頁面之間切換。

    顯示修訂的 Django 應用程式螢幕快照,該應用程式會使用範本繼承來轉譯所有頁面的標頭和導覽列。

  7. 完成時,請停止應用程式並儲存項目變更。

  8. 因為您對應用程式做了大量變更,所以最好將變更儲存至 Git 存放庫。 如需詳細資訊,請參閱本教學課程系列第 2 步驟的 提交版本控制變更

下一步