Django 設定檔深入解析:settings.py 完全指南 | Django 教學
在 Django 專案中, settings.py 是整個應用程式的配置中心(Configuration Center),從資料庫連線、安全金鑰到靜態檔案路徑,所有核心行為都由這個檔案控制。理解 settings.py 中每一項設定的用途與最佳實踐,是從 Django 初學者邁向專業開發者的必經之路。本文將逐一拆解 DEBUG、SECRET_KEY、DATABASES、MIDDLEWARE 等關鍵設定,並介紹如何使用 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 安全守則
- 絕不可 將 SECRET_KEY 提交到版本控制系統(Git)
- 開發環境與生產環境使用 不同 的 SECRET_KEY
- SECRET_KEY 長度建議至少 50 個字元
- 如果懷疑金鑰已洩漏,應立即更換並強制所有使用者重新登入
# 使用 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 的順序會影響以下行為:
- Template 覆寫:排在前面的 App 的 Template 會覆蓋後面同名的 Template。如果你想自訂 Django Admin 的 Template,自訂 App 需要放在
django.contrib.admin之前。 - Management Command:同名的指令會以最後載入的 App 為準。
- 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'
靜態檔案查找順序
- Django 先搜尋
STATICFILES_DIRS中列出的目錄 - 接著搜尋每個已安裝 App 的
static/子目錄 - 在生產環境部署前,執行
python manage.py collectstatic,將所有靜態檔案集中到STATIC_ROOT,再由 Nginx 等 Web 伺服器提供服務
使用者上傳檔案設定:MEDIA_URL / MEDIA_ROOT
MEDIA_URL 和 MEDIA_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 變數
],
},
},
]
模板查找順序
- 優先搜尋
DIRS中指定的目錄 - 當
APP_DIRS = True時,接著搜尋每個 INSTALLED_APPS 中 App 的templates/子目錄 - 如果要覆寫第三方套件的 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 結構。