Django 設定檔深入解析:settings.py 完全指南 | Django 教學

2026/05/26 2026/05/22
Django 設定檔深入解析:settings.py 完全指南 | Django 教學

在 Django 專案中, settings.py 是整個應用程式的配置中心(Configuration Center),從資料庫連線、安全金鑰到靜態檔案路徑,所有核心行為都由這個檔案控制。理解 settings.py 中每一項設定的用途與最佳實踐,是從 Django 初學者邁向專業開發者的必經之路。本文將逐一拆解 DEBUGSECRET_KEYDATABASESMIDDLEWARE 等關鍵設定,並介紹如何使用 python-decouple 管理環境變數,讓你的 Django 專案同時兼顧開發便利性與生產環境安全性。

settings.py 在 Django 中的角色

當你透過 django-admin startproject myproject 建立專案時,Django 會自動產生 myproject/settings.py。這個檔案是 Django 的核心配置模組(Configuration Module),Django 在啟動時會讀取 DJANGO_SETTINGS_MODULE 環境變數來定位它,並據此初始化整個應用程式。

# manage.py 中的預設設定
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

settings.py 本質上就是一個普通的 Python 模組,你可以在裡面使用任何 Python 語法,包括條件判斷、函式呼叫、甚至 import 其他模組。Django 會讀取其中所有大寫的變數作為設定項。


DEBUG 模式:開發 vs 生產

DEBUG 是 Django 中最重要的安全開關之一,它決定了 Django 在遇到錯誤時的行為。

# 開發環境:開啟 DEBUG 模式
DEBUG = True

# 生產環境:必須關閉 DEBUG 模式
DEBUG = False

開發環境(DEBUG = True)

  • 錯誤頁面會顯示完整的追蹤資訊(Traceback),包括原始碼、本地變數、SQL 查詢記錄
  • Django 會在記憶體中累積所有已執行的 SQL 查詢,方便除錯
  • 靜態檔案由 Django 開發伺服器自動提供

生產環境(DEBUG = False)

  • 錯誤頁面只顯示簡潔的 HTTP 錯誤碼(如 404、500)
  • 不會洩漏任何敏感的程式碼或資料庫資訊
  • 必須搭配 ALLOWED_HOSTS 設定,否則 Django 會拒絕所有請求

在生產環境中忘記關閉 DEBUG 是 Django 最常見的安全失誤之一。當 DEBUG = True 時,任何訪客都能透過觸發錯誤來查看你的程式碼結構與資料庫架構。


SECRET_KEY 安全性

SECRET_KEY 是 Django 用於加密簽名(Cryptographic Signing)的核心金鑰,應用範圍包括:

  • Session 資料簽名
  • CSRF Token 產生
  • 密碼重設 Token
  • 任何使用 django.core.signing 的操作
# Django 自動產生的 SECRET_KEY(僅供開發使用)
SECRET_KEY = 'django-insecure-abc123...'

# 正式環境:從環境變數讀取
import os
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')

SECRET_KEY 安全守則

  1. 絕不可 將 SECRET_KEY 提交到版本控制系統(Git)
  2. 開發環境與生產環境使用 不同 的 SECRET_KEY
  3. SECRET_KEY 長度建議至少 50 個字元
  4. 如果懷疑金鑰已洩漏,應立即更換並強制所有使用者重新登入
# 使用 Django 內建工具產生安全的 SECRET_KEY
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())
# 輸出範例:'v$2x!k8g#m^r7&9_qwp...'

ALLOWED_HOSTS 設定

ALLOWED_HOSTS 是一個字串清單(List),定義了 Django 應用程式允許接受請求的主機名稱(Host)或域名(Domain)。當 DEBUG = False 時,如果請求的 Host 標頭不在此清單中,Django 會回傳 400 Bad Request

# 開發環境
ALLOWED_HOSTS = ['localhost', '127.0.0.1']

# 生產環境:設定實際域名
ALLOWED_HOSTS = ['example.com', 'www.example.com']

# 允許所有子域名(使用前綴 . 號)
ALLOWED_HOSTS = ['.example.com']

# 危險!不建議在生產環境使用萬用字元
ALLOWED_HOSTS = ['*']

這項設定是防範 HTTP Host Header 攻擊(HTTP Host 標頭攻擊)的重要機制。攻擊者可能透過偽造 Host 標頭來注入惡意連結到密碼重設信件或快取投毒。


INSTALLED_APPS 詳解

INSTALLED_APPS 是一個清單,列出了 Django 專案中所有啟用的應用程式(Application)。只有在此清單中註冊的 App,Django 才會載入其 Model、Template Tag、靜態檔案及管理介面設定。

INSTALLED_APPS = [
    # === Django 內建 App ===
    'django.contrib.admin',          # 管理後台
    'django.contrib.auth',           # 認證系統
    'django.contrib.contenttypes',   # Content Type 框架
    'django.contrib.sessions',       # Session 框架
    'django.contrib.messages',       # 訊息框架
    'django.contrib.staticfiles',    # 靜態檔案管理

    # === 第三方套件 ===
    'rest_framework',                # Django REST Framework
    'corsheaders',                   # CORS 跨域設定
    'django_extensions',             # 開發工具擴充

    # === 自訂 App ===
    'apps.users.apps.UsersConfig',   # 使用者管理
    'apps.articles',                 # 文章管理
]

排列順序的重要性

INSTALLED_APPS 的順序會影響以下行為:

  1. Template 覆寫:排在前面的 App 的 Template 會覆蓋後面同名的 Template。如果你想自訂 Django Admin 的 Template,自訂 App 需要放在 django.contrib.admin 之前。
  2. Management Command:同名的指令會以最後載入的 App 為準。
  3. Signal 連接AppConfig.ready() 按照 INSTALLED_APPS 的順序依次執行。

建議的排列慣例是:Django 內建 App 在最前面,接著是第三方套件,最後是自訂 App。


DATABASES 設定

DATABASES 設定定義了 Django 專案的資料庫連線(Database Connection)資訊。Django 支援多種資料庫後端(Database Backend),包括 SQLite、PostgreSQL、MySQL 和 Oracle。

預設 SQLite 設定

Django 新專案預設使用 SQLite,它是一個輕量級的檔案型資料庫(File-based Database),不需要額外安裝資料庫伺服器,非常適合開發與測試環境。

# 預設的 SQLite 設定
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

切換到 PostgreSQL

在生產環境中,建議使用 PostgreSQL 等企業級資料庫。切換前需要先安裝資料庫驅動程式(Database Driver)。

# 安裝 PostgreSQL 驅動
pip install psycopg2-binary
# PostgreSQL 設定範例
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myproject_db',        # 資料庫名稱
        'USER': 'myproject_user',      # 資料庫使用者
        'PASSWORD': 'secure_password', # 資料庫密碼
        'HOST': 'localhost',           # 資料庫主機
        'PORT': '5432',               # 預設 PostgreSQL 端口
        'OPTIONS': {
            'connect_timeout': 10,     # 連線逾時(秒)
        },
    }
}

資料庫密碼等敏感資訊應透過環境變數管理,不要直接寫在 settings.py 中。本文最後一節會介紹具體做法。


靜態檔案設定:STATIC_URL / STATICFILES_DIRS / STATIC_ROOT

Django 將靜態檔案(Static Files)分為「開發時期」與「部署時期」兩種管理方式,對應不同的設定項。

# 靜態檔案的 URL 前綴
# 瀏覽器存取靜態檔案時使用此路徑,例如 /static/css/style.css
STATIC_URL = '/static/'

# 額外的靜態檔案目錄(開發時期使用)
# Django 開發伺服器會從這些目錄中查找靜態檔案
STATICFILES_DIRS = [
    BASE_DIR / 'static',          # 專案根目錄下的 static 資料夾
    BASE_DIR / 'assets',          # 也可以指定其他目錄
]

# collectstatic 指令的目標目錄(部署時期使用)
# 執行 python manage.py collectstatic 後,所有靜態檔案會被收集到此目錄
STATIC_ROOT = BASE_DIR / 'staticfiles'

靜態檔案查找順序

  1. Django 先搜尋 STATICFILES_DIRS 中列出的目錄
  2. 接著搜尋每個已安裝 App 的 static/ 子目錄
  3. 在生產環境部署前,執行 python manage.py collectstatic,將所有靜態檔案集中到 STATIC_ROOT,再由 Nginx 等 Web 伺服器提供服務

使用者上傳檔案設定:MEDIA_URL / MEDIA_ROOT

MEDIA_URLMEDIA_ROOT 用於管理使用者上傳的檔案(User-uploaded Files),例如頭像、文件附件等。

# 使用者上傳檔案的 URL 前綴
MEDIA_URL = '/media/'

# 使用者上傳檔案的實際儲存路徑
MEDIA_ROOT = BASE_DIR / 'media'

在開發環境中,需要在 urls.py 中加入以下設定,讓 Django 開發伺服器能提供上傳檔案的存取服務:

# myproject/urls.py
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... 其他 URL 設定
]

# 僅在 DEBUG 模式下提供 media 檔案服務
if settings.DEBUG:
    urlpatterns += static(
        settings.MEDIA_URL,
        document_root=settings.MEDIA_ROOT
    )

在生產環境中,使用者上傳的檔案應由 Nginx 或雲端儲存服務(如 AWS S3)提供,而不是由 Django 處理。


TEMPLATES 設定

TEMPLATES 設定定義了 Django 的模板引擎(Template Engine)配置,包括模板查找路徑和可用的上下文處理器(Context Processor)。

TEMPLATES = [
    {
        # 使用 Django 內建的模板引擎
        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        # 全域模板目錄(優先查找)
        'DIRS': [BASE_DIR / 'templates'],

        # 是否自動搜尋每個 App 的 templates/ 子目錄
        'APP_DIRS': True,

        'OPTIONS': {
            # 上下文處理器:自動注入到每個 Template 的變數
            'context_processors': [
                'django.template.context_processors.debug',    # debug 變數
                'django.template.context_processors.request',  # request 物件
                'django.contrib.auth.context_processors.auth', # user、perms 變數
                'django.contrib.messages.context_processors.messages',  # messages 變數
            ],
        },
    },
]

模板查找順序

  1. 優先搜尋 DIRS 中指定的目錄
  2. APP_DIRS = True 時,接著搜尋每個 INSTALLED_APPS 中 App 的 templates/ 子目錄
  3. 如果要覆寫第三方套件的 Template(例如 Django Admin),將自訂 Template 放在 DIRS 指定的目錄中即可

MIDDLEWARE 設定順序

Middleware(中介軟體)是 Django 請求/回應處理流程中的「管線」。每一個 HTTP 請求都會依序通過所有 Middleware,回應時則以相反順序通過。

MIDDLEWARE = [
    # 安全性中介軟體(必須放在最前面)
    'django.middleware.security.SecurityMiddleware',

    # Session 中介軟體(認證之前必須先有 Session)
    'django.contrib.sessions.middleware.SessionMiddleware',

    # 通用中介軟體(處理 URL 尾端斜線、Content-Length 等)
    'django.middleware.common.CommonMiddleware',

    # CSRF 防護(表單提交前必須驗證)
    'django.middleware.csrf.CsrfViewMiddleware',

    # 認證中介軟體(依賴 Session,因此必須在 SessionMiddleware 之後)
    'django.contrib.auth.middleware.AuthenticationMiddleware',

    # 訊息框架中介軟體
    'django.contrib.messages.middleware.MessageMiddleware',

    # 防止頁面被嵌入 iframe(點擊劫持防護)
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Middleware 執行順序圖解

HTTP 請求進入
    ↓ SecurityMiddleware          ← 請求階段:由上至下
    ↓ SessionMiddleware
    ↓ CommonMiddleware
    ↓ CsrfViewMiddleware
    ↓ AuthenticationMiddleware
    ↓ MessageMiddleware
    ↓ XFrameOptionsMiddleware
    ↓
    ↓ ===== View 處理 =====
    ↓
    ↑ XFrameOptionsMiddleware     ← 回應階段:由下至上
    ↑ MessageMiddleware
    ↑ AuthenticationMiddleware
    ↑ CsrfViewMiddleware
    ↑ CommonMiddleware
    ↑ SessionMiddleware
    ↑ SecurityMiddleware
HTTP 回應返回

順序錯誤可能導致嚴重問題。例如將 AuthenticationMiddleware 放在 SessionMiddleware 之前,會因為 Session 尚未初始化而無法識別使用者身份。


國際化設定

Django 內建強大的國際化(Internationalization,簡稱 i18n)與在地化(Localization,簡稱 l10n)支援,以下是相關設定項。

# 預設語言代碼
# 使用 IETF 語言標籤格式,如 'en-us'、'zh-hant'
LANGUAGE_CODE = 'zh-hant'

# 預設時區
# 完整清單:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TIME_ZONE = 'Asia/Taipei'

# 是否啟用 Django 的翻譯系統
# True:Django 會根據使用者的語言偏好提供對應的翻譯
USE_I18N = True

# 是否啟用時區感知(Timezone-aware)的日期時間處理
# True:資料庫儲存 UTC 時間,顯示時自動轉換為 TIME_ZONE 指定的時區
USE_TZ = True

USE_TZ 的實際影響

# 當 USE_TZ = True 時
from django.utils import timezone

# 正確做法:使用 timezone-aware 的時間
now = timezone.now()  # 回傳 UTC 時間,帶有時區資訊

# 錯誤做法:使用 naive datetime(不帶時區資訊)
import datetime
now = datetime.datetime.now()  # 這在 USE_TZ = True 時可能引發警告

建議在專案初始就設定 USE_TZ = True。資料庫統一使用 UTC 儲存,前端顯示時再轉換為使用者所在時區,這是處理多時區應用的最佳實踐。


環境變數管理:python-decouple

到目前為止,我們看到 SECRET_KEY、資料庫密碼等敏感資訊都不應該直接寫在 settings.py 中。python-decouple 是一個輕量且專注的環境變數管理套件,能夠將設定與程式碼分離。

# 安裝 python-decouple
pip install python-decouple

建立 .env 檔案

在專案根目錄建立 .env 檔案,存放所有敏感設定:

# .env(此檔案不可提交至 Git)
DJANGO_SECRET_KEY=v$2x!k8g#m^r7&9_qwp...your-actual-secret-key
DJANGO_DEBUG=True
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1
DB_ENGINE=django.db.backends.postgresql
DB_NAME=myproject_db
DB_USER=myproject_user
DB_PASSWORD=secure_password
DB_HOST=localhost
DB_PORT=5432

記得在 .gitignore 中加入 .env

# .gitignore
.env

在 settings.py 中使用 python-decouple

# settings.py
from decouple import config, Csv
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

# 安全金鑰:從環境變數讀取,沒有預設值(未設定時會報錯)
SECRET_KEY = config('DJANGO_SECRET_KEY')

# DEBUG 模式:自動將字串轉為布林值,預設為 False
DEBUG = config('DJANGO_DEBUG', default=False, cast=bool)

# ALLOWED_HOSTS:使用 Csv() 將逗號分隔的字串轉為 List
ALLOWED_HOSTS = config('DJANGO_ALLOWED_HOSTS', default='', cast=Csv())

# 資料庫設定
DATABASES = {
    'default': {
        'ENGINE': config('DB_ENGINE', default='django.db.backends.sqlite3'),
        'NAME': config('DB_NAME', default=str(BASE_DIR / 'db.sqlite3')),
        'USER': config('DB_USER', default=''),
        'PASSWORD': config('DB_PASSWORD', default=''),
        'HOST': config('DB_HOST', default=''),
        'PORT': config('DB_PORT', default=''),
    }
}

python-decouple 的 config() 方法

from decouple import config, Csv

# 基本讀取(字串)
secret = config('DJANGO_SECRET_KEY')

# 型別轉換:cast 參數
debug = config('DJANGO_DEBUG', cast=bool)           # 字串 → 布林值
port = config('DB_PORT', cast=int)                   # 字串 → 整數
hosts = config('ALLOWED_HOSTS', cast=Csv())          # 逗號分隔字串 → List

# 預設值:當環境變數不存在時使用
timeout = config('REQUEST_TIMEOUT', default=30, cast=int)

使用 python-decouple 的好處是:同一份 settings.py 可以在不同環境中運行,只需要更換 .env 檔案或設定環境變數即可,不需要維護多份設定檔。


總結

settings.py 是 Django 專案的控制中樞,每一項設定都直接影響應用程式的行為、效能與安全性。讓我們回顧本文的重點:

  • DEBUG:開發環境設為 True 以便除錯,生產環境 必須 設為 False,避免洩漏敏感資訊。
  • SECRET_KEY:加密簽名的核心金鑰,絕不可提交至版本控制系統,應透過環境變數管理。
  • ALLOWED_HOSTS:防範 Host Header 攻擊的白名單,DEBUG = False 時必須明確設定。
  • INSTALLED_APPS:App 註冊清單,排列順序會影響 Template 覆寫與 Management Command 的優先權。
  • DATABASES:開發環境可用 SQLite,生產環境建議切換至 PostgreSQL,密碼等敏感資訊從環境變數讀取。
  • STATIC_URL / STATICFILES_DIRS / STATIC_ROOT:分別對應靜態檔案的 URL 前綴、開發時期搜尋目錄、部署時期收集目標。
  • MEDIA_URL / MEDIA_ROOT:使用者上傳檔案的 URL 前綴與儲存路徑,生產環境應交由 Nginx 或雲端儲存處理。
  • TEMPLATES:模板引擎配置,APP_DIRS = True 可自動搜尋各 App 的模板目錄。
  • MIDDLEWARE:順序至關重要,SecurityMiddleware 放最前、認證相關 Middleware 必須在 Session 之後。
  • 國際化設定USE_TZ = True 確保時區感知,資料庫統一使用 UTC 儲存是最佳實踐。
  • python-decouple:將敏感資訊與程式碼分離,同一份 settings.py 可適用於所有環境。

掌握這些設定項,你就能自信地配置一個安全、可維護且符合生產標準的 Django 專案。下一篇我們將深入探討 Django 的 URL 路由系統,學習如何設計清晰、RESTful 的 URL 結構。

BenZ Software Developer

熱愛技術的軟體開發者,在這裡分享程式開發經驗與學習筆記。