跳轉到

Django 與 Bootstrap

開始之前

任務目標

在這個章節中,我們會完成:

  • 了解 Bootstrap 框架
  • 安裝並設定 django-bootstrap5
  • 美化文章列表與詳細頁面

什麼是 Bootstrap?

Bootstrap 是世界上最受歡迎的前端框架,提供了大量預先設計好的 CSS 和 JavaScript 元件,讓你可以快速建立美觀且響應式的網頁。

Bootstrap 的特色

特色 說明
響應式設計 自動適應不同螢幕尺寸(手機、平板、電腦)
元件豐富 按鈕、表單、導覽列、卡片等現成元件
易於使用 只需要加上 CSS class 就能套用樣式
客製化 可以自訂顏色、間距等設計
跨瀏覽器 支援各種現代瀏覽器

Bootstrap 的核心概念

Grid System(格線系統)

Bootstrap 使用 12 欄位的格線系統來排版:

<div class="container">
  <div class="row">
    <div class="col-md-8">主要內容(佔 8 欄)</div>
    <div class="col-md-4">側邊欄(佔 4 欄)</div>
  </div>
</div>

Utility Classes(工具類別)

Bootstrap 提供大量工具類別來快速調整樣式。

傳統原生 CSS 寫法

<!-- 需要自己定義 class 名稱 -->
<div class="header-title">上方間距</div>
<div class="content-section">下方間距</div>
<div class="card-body">內距</div>

<button class="primary-button">主要按鈕</button>
<button class="success-button">成功按鈕</button>
<button class="danger-button">危險按鈕</button>
/* 然後需要寫大量的 CSS */
.header-title {
  margin-top: 1rem;
}

.content-section {
  margin-bottom: 1.5rem;
}

.card-body {
  padding: 1rem;
}

.primary-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
}

.success-button {
  background-color: #28a745;
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
}

.danger-button {
  background-color: #dc3545;
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 0.25rem;
  cursor: pointer;
}

使用 Bootstrap Utility Classes

<!-- 直接使用 Bootstrap 提供的 class,不需要寫 CSS -->
<div class="mt-3">上方間距</div>
<div class="mb-4">下方間距</div>
<div class="p-3">內距</div>

<button class="btn btn-primary">主要按鈕</button>
<button class="btn btn-success">成功按鈕</button>
<button class="btn btn-danger">危險按鈕</button>

Bootstrap Utility Classes 的優勢

  • 快速開發:不需要思考 class 名稱,不需要寫 CSS
  • 一致性:整個專案使用相同的間距和顏色系統
  • 響應式:可以搭配斷點使用,如 mt-md-5(中螢幕以上才套用)
  • 易於維護:看 HTML 就知道樣式,不需要跳到 CSS 檔案查看
  • 減少檔案大小:不需要為每個元素寫重複的 CSS

常用的 Utility Classes:

Class 說明 等同的 CSS
mt-3 上方間距 margin-top: 1rem;
mb-4 下方間距 margin-bottom: 1.5rem;
p-3 內距 padding: 1rem;
text-center 文字置中 text-align: center;
d-flex Flexbox display: flex;
bg-light 淺色背景 background-color: #f8f9fa;

Components(元件)

Bootstrap 提供許多現成的元件:

  • Card(卡片):展示內容的容器
  • Navbar(導覽列):網站導覽
  • Modal(彈窗):對話框
  • Form(表單):美化的表單元件

Bootstrap 版本

目前 Bootstrap 最新版本是 v5.x,本教學使用 Bootstrap 5。

官方文件:https://getbootstrap.com/docs/5.3/getting-started/introduction/

安裝 django-bootstrap5

在 Django 中使用 Bootstrap 有多種方式:

  1. 直接在 template 中引入 Bootstrap CDN
  2. 下載 Bootstrap 檔案放到 static 資料夾
  3. 使用 django-bootstrap5 套件(推薦)

方法比較

傳統方式:直接使用 CDN

<!DOCTYPE html>
<html>
  <head>
    <!-- 需要手動引入 Bootstrap CSS -->
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <!-- 你的內容 -->

    <!-- 需要手動引入 Bootstrap JavaScript -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  </body>
</html>

這種方式的缺點:

  • 需要手動管理 CDN 連結
  • 無法方便地自訂 Bootstrap 設定
  • 表單需要自己寫 HTML 套用 Bootstrap 樣式
  • 版本更新時需要手動修改所有連結

使用 django-bootstrap5(推薦)

{% load django_bootstrap5 %}

<!DOCTYPE html>
<html>
  <head>
    <!-- 一行搞定 CSS -->
    {% bootstrap_css %}
  </head>
  <body>
    <!-- 你的內容 -->

    <!-- 一行搞定 JavaScript -->
    {% bootstrap_javascript %}
  </body>
</html>

這種方式的優點:

  • 使用 template tag,簡潔易讀
  • 可以在 settings.py 中統一管理版本和設定
  • 提供 {% bootstrap_form %} 自動渲染表單
  • 支援離線開發
  • 版本更新只需要升級套件

django-bootstrap5 官方文件

django-bootstrap5 是一個整合 Bootstrap 5 與 Django 的第三方套件。

安裝套件

使用 uv 安裝 django-bootstrap5:

uv add django-bootstrap5

註冊 App

core/settings.pyINSTALLED_APPS 中加入 django_bootstrap5

core/settings.py
INSTALLED_APPS = [
    # Django 內建 apps
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # 第三方 apps
    "django_bootstrap5",  # (1)!
    # 本地 apps
    "practices",
    "blog",
]
  1. 注意是底線 django_bootstrap5,不是 dash

INSTALLED_APPS 的順序

Django 建議的順序:

  1. Django 內建 apps:如 adminauth
  2. 第三方 apps:如 django_bootstrap5rest_framework
  3. 本地 apps:自己開發的 apps

順序的影響

  • Template 載入:Django 會依照順序搜尋 templates,先找到的優先使用
  • Static files:同樣依照順序搜尋靜態檔案
  • Admin 客製化:如果要覆寫 admin 的 template,需要把 app 放在 admin 之前
  • Migration 依賴:如果 app 之間有 ForeignKey 關係,Django 會自動處理,但維持一致的順序是好習慣

美化基礎樣板

讓我們更新專案級的 base.html,加入 Bootstrap:

templates/base.html
{% load django_bootstrap5 %}

<!DOCTYPE html>
<html lang="zh-Hant">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Django Playground" />
    <meta name="keywords" content="Django, Playground" />

    <title>
      {% block title %}
        Django 大冒險
      {% endblock title %}
    </title>

    {% bootstrap_css %}  <!-- (1)! -->

    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" />  <!-- (2)! -->

    {% block extra_head %}
    {% endblock extra_head %}
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">  <!-- (3)! -->
      <div class="container">
        <span class="navbar-brand">Django 大冒險</span>
        <button class="navbar-toggler"
                type="button"
                data-bs-toggle="collapse"
                data-bs-target="#navbarNav">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav ms-auto">
            <li class="nav-item">
              <a class="nav-link" href="{% url 'article_list' %}">文章列表</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="{% url 'admin:index' %}">管理後台</a>  <!-- (4)! -->
            </li>
          </ul>
        </div>
      </div>
    </nav>

    <main class="container my-4">  <!-- (5)! -->
      {% block content %}
      {% endblock content %}
    </main>

    <footer class="bg-light py-4 mt-5">  <!-- (6)! -->
      <div class="container text-center">
        <p class="text-muted mb-0">
          Django Playground
        </p>
      </div>
    </footer>

    {% bootstrap_javascript %}  <!-- (7)! -->

    {% block extra_scripts %}
    {% endblock extra_scripts %}
  </body>
</html>
  1. 載入 Bootstrap CSS
  2. 載入 Bootstrap Icons 圖示字型
  3. Bootstrap 的導覽列元件
  4. admin:index 中的 : 用於指定 app namespace,格式為 app_name:url_name(後續章節會詳細說明)
  5. 容器 + 上下間距
  6. 淺色背景 + 內距
  7. 載入 Bootstrap JavaScript

Bootstrap Class 說明

  • navbar:導覽列元件
  • navbar-expand-lg:在大螢幕展開,小螢幕收合
  • navbar-dark bg-dark:深色主題
  • container:固定寬度的容器
  • my-4:上下間距(margin y-axis)
  • py-4:上下內距(padding y-axis)
  • text-muted:柔和的文字顏色

完整的 Bootstrap class 可以參考官方文件

Bootstrap Icons

Bootstrap Icons 是官方提供的圖示字型庫,包含超過 1,800 個圖示。

使用方式:<i class="bi bi-{icon-name}"></i>

完整圖示列表:https://icons.getbootstrap.com/

美化 App 級基礎樣板

首先,讓我們更新 blog/base.html,為側邊欄加入 Bootstrap 樣式:

blog/templates/blog/base.html
{% extends "base.html" %}

{% block content %}
  <div class="row">
    <aside class="col-md-3 mb-4">
      <div class="card">
        <div class="card-body">
          <h5 class="card-title">
            文章管理
          </h5>
          <ul class="list-group list-group-flush">
            <li class="list-group-item">
              <a href="{% url 'article_list' %}" class="text-decoration-none">文章列表</a>
            </li>
          </ul>
        </div>
      </div>
    </aside>

    <div class="col-md-9">
      {% block blog_content %}
      {% endblock blog_content %}
    </div>
  </div>
{% endblock content %}

美化文章卡片元件

接著更新文章卡片元件,使用 Bootstrap Card:

blog/templates/blog/components/article_card.html
<div class="col-md-6 col-lg-4 mb-4">  <!-- (1)! -->
  <div class="card h-100">  <!-- (2)! -->
    <div class="card-body">
      <h5 class="card-title">  <!-- (3)! -->
        {{ article.title }}
      </h5>
      <h6 class="card-subtitle mb-2 text-muted">  <!-- (4)! -->
        {{ article.author.name }}
      </h6>
      <p class="card-text">
        {{ article.content|truncatewords:30 }}  <!-- (5)! -->
      </p>
    </div>
    <div class="card-footer bg-transparent">  <!-- (6)! -->
      <small class="text-muted">
        {{ article.created_at|date:"Y-m-d H:i" }}  <!-- (7)! -->
      </small>
      <a href="{% url 'article_detail' article.id %}"
         class="btn btn-primary btn-sm float-end">  <!-- (8)! -->
        閱讀更多
      </a>
    </div>
  </div>
</div>
  1. 響應式欄位:中螢幕 2 欄、大螢幕 3 欄
  2. 卡片元件,高度 100%
  3. 卡片標題
  4. 卡片副標題,柔和顏色
  5. 截斷為 30 個字
  6. 透明背景的卡片頁尾
  7. 格式化日期時間
  8. 主要按鈕,小尺寸,靠右對齊

美化文章列表頁

現在更新文章列表頁,加入 Bootstrap 的格線系統:

blog/templates/blog/article_list.html
{% extends "blog/base.html" %}

{% block title %}
  文章列表 - Django 大冒險
{% endblock title %}

{% block blog_content %}
  <h2 class="mb-4">  <!-- (1)! -->
    文章列表
  </h2>
  <div class="row">
    {% for article in articles %}
      {% include "blog/components/article_card.html" %}
    {% empty %}
      <div class="col-12">
        <div class="alert alert-info">  <!-- (2)! -->
          目前沒有文章
        </div>
      </div>
    {% endfor %}
  </div>
{% endblock blog_content %}
  1. 標題 + 下方間距
  2. 資訊提示框

Bootstrap 格線系統

  • col-md-6:中等螢幕(≥768px)每列顯示 2 個(12 ÷ 6 = 2)
  • col-lg-4:大螢幕(≥992px)每列顯示 3 個(12 ÷ 4 = 3)
  • mb-4:下方間距 4

在小螢幕(<768px)時,每個卡片會自動佔滿整列。

美化文章詳細頁

接著使用 Bootstrap 來美化文章詳細頁。我們會加入麵包屑導航、卡片樣式、標籤徽章等元件:

blog/templates/blog/article_detail.html
{% extends "blog/base.html" %}

{% block title %}
  {{ article.title }} - Django 大冒險
{% endblock title %}

{% block blog_content %}
  <nav aria-label="breadcrumb">  <!-- (1)! -->
    <ol class="breadcrumb">
      <li class="breadcrumb-item">
        <a href="{% url 'article_list' %}">文章列表</a>
      </li>
      <li class="breadcrumb-item active">
        {{ article.title }}
      </li>
    </ol>
  </nav>

  <article class="card">
    <div class="card-body">
      <h1 class="card-title">
        {{ article.title }}
      </h1>

      <div class="d-flex align-items-center mb-3 text-muted">  <!-- (2)! -->
        <span class="me-3">  <!-- (3)! -->
          <i class="bi bi-person"></i>  <!-- (4)! -->
          作者:{{ article.author.name }}
        </span>
        <span>
          <i class="bi bi-calendar"></i>
          發布時間:{{ article.created_at|date:"Y-m-d H:i" }}
        </span>
      </div>

      {% if article.tags.exists %}  <!-- (5)! -->
        <div class="mb-3">
          {% for tag in article.tags.all %}
            <span class="badge bg-secondary me-1">{{ tag.name }}</span>  <!-- (6)! -->
          {% endfor %}
        </div>
      {% endif %}

      <hr />  <!-- (7)! -->

      <div class="article-content">
        {{ article.content|linebreaks }}  <!-- (8)! -->
      </div>
    </div>

    <div class="card-footer bg-light">
      <a href="{% url 'article_list' %}" class="btn btn-outline-secondary">
        <i class="bi bi-arrow-left"></i> 返回列表  <!-- (9)! -->
      </a>
    </div>
  </article>
{% endblock blog_content %}
  1. 麵包屑導航
  2. Flex 佈局,垂直置中對齊
  3. 右側間距
  4. Bootstrap Icons 圖示
  5. 檢查是否有標籤
  6. 徽章元件
  7. 分隔線
  8. 自動將換行轉換為 <br><p>
  9. Bootstrap icon 左側箭頭

常見問題

為什麼要用 django-bootstrap5 而不是直接用 CDN?

使用 django-bootstrap5 的好處:

  1. 提供 template tags,讓 Bootstrap 整合更簡潔
  2. 可以在 settings.py 中統一管理版本和選項
  3. 支援離線開發(不需要網路)
  4. 後續可以使用 {% bootstrap_form %} 自動渲染表單
  5. 更容易自訂 Bootstrap 的設定

當然,如果只是簡單的靜態頁面,直接用 CDN 也可以。

如何自訂 Bootstrap 的顏色?

可以在 settings.py 中設定:

BOOTSTRAP5 = {
    "theme_url": None,  # 使用自訂 CSS
    "css_url": {
        "href": "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css",
    },
}

或者自己下載 Bootstrap 原始碼,修改 SCSS 變數後重新編譯。

Bootstrap 會影響效能嗎?

Bootstrap CSS 和 JavaScript 檔案不算小,但有幾種最佳化方式:

  1. 使用 CDN(瀏覽器可能已快取)
  2. 只引入需要的元件(使用 Bootstrap 客製化工具)
  3. 使用壓縮版本(.min.css.min.js
  4. 啟用瀏覽器快取

對於大多數專案來說,Bootstrap 的效能影響可以忽略不計。

任務結束

完成!

恭喜你完成了這個章節!現在你已經:

  • 了解 Bootstrap 框架
  • 安裝並設定 django-bootstrap5
  • 美化文章列表與詳細頁面

補充說明

Bootstrap 是前端開發的強大工具,可以大幅加快網頁開發速度。掌握 Bootstrap 後:

  • 可以快速建立專業級的使用者介面
  • 不需要從零開始寫 CSS
  • 網站自動支援響應式設計

在實際專案中,建議:

  • 熟悉 Bootstrap 的 Grid System
  • 善用 Utility Classes 快速調整樣式
  • 參考 Bootstrap 官方範例
  • 根據需求客製化顏色和樣式

下一步可以學習:

  • 使用 Bootstrap 的 JavaScript 元件(Modal、Dropdown 等)
  • 自訂 Bootstrap 主題
  • 結合 Django Form 與 Bootstrap(將在後續章節介紹)