Django 配置方法
Django 配置方法全面指南
配置是任何 Django 项目的核心骨架。正确理解 settings.py 的结构、环境分离、敏感信息管理以及生产环境优化,是每个 Django 开发者必备的技能。本教程将带你从基础配置逐步深入到多环境管理、12-Factor 风格配置以及安全最佳实践。
基础配置文件结构
当你通过 django-admin startproject myproject 创建项目时,会自动生成一个 myproject/settings.py 文件。这个模块实际上就是一个普通的 Python 模块,Django 通过它来初始化整个应用。
import os
from pathlib import Path
# 项目根目录
BASE_DIR = Path(__file__).resolve().parent.parent
# 安全密钥,绝对不可泄露
SECRET_KEY = 'django-insecure-xxxxx'
# 调试模式
DEBUG = True
ALLOWED_HOSTS = []
# 应用定义
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 你自己的应用
'myapp',
]
所有配置项都是大写字母,这是 Django 的约定,也便于区分变量和配置。你可以把配置项简单划分为几大类:
- 核心配置:
SECRET_KEY,DEBUG,ALLOWED_HOSTS,ROOT_URLCONF,WSGI_APPLICATION - 数据库:
DATABASES - 国际化与本地化:
LANGUAGE_CODE,TIME_ZONE,USE_I18N,USE_TZ - 静态文件与媒体文件:
STATIC_URL,STATIC_ROOT,MEDIA_URL,MEDIA_ROOT - 中间件与模板:
MIDDLEWARE,TEMPLATES - 安全与性能:安全相关的头信息、缓存、会话引擎等
必知必会的核心配置项
SECRET_KEY 与安全
SECRET_KEY 是 Django 最重要的安全配置,用于加密签名( session 、 CSRF 令牌、密码重置令牌等)。绝对不要把它硬编码在代码中,更不能提交到版本控制系统。
生产环境中,应该从环境变量获取:
import os
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
如果没有设置环境变量,可以添加一个回退,但仅用于开发:
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'dev-only-key-change-in-production')
生成安全密钥的简单方式:
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
DEBUG 模式
DEBUG = True 仅在本地开发时启用。它提供详细的错误页面、SQL 查询日志等便利功能,但在生产环境中开启会暴露大量敏感信息,严重危及安全。生产环境必须设为 False。
同时,当 DEBUG=False 时,必须正确设置 ALLOWED_HOSTS,否则会收到 400 Bad Request。
DEBUG = os.environ.get('DJANGO_DEBUG', 'False') == 'True'
ALLOWED_HOSTS 配置
该列表包含允许的域名/IP,Django 通过 Host 请求头验证请求。在生产环境中,你一定要列出你自己的域名:
ALLOWED_HOSTS = ['example.com', 'www.example.com', '127.0.0.1']
也可以从环境变量中解析:
import os
ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', '').split(',')
数据库配置
DATABASES 是一个字典,必须包含 default 连接。默认使用 SQLite,适合开发和小型项目。对于生产环境,通常使用 PostgreSQL、MySQL 或 MariaDB。
PostgreSQL 示例(从环境变量读取):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'mydatabase'),
'USER': os.environ.get('DB_USER', 'myuser'),
'PASSWORD': os.environ.get('DB_PASSWORD', ''),
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', '5432'),
}
}
其他常用后端引擎:
django.db.backends.mysqldjango.db.backends.sqlite3
静态文件与媒体文件
静态文件(CSS, JS, 图片等)在生产环境中需要收集到统一目录,并由服务器(如 Nginx)直接提供服务。
# 开发环境 STATIC_URL 指向应用内的静态文件夹
STATIC_URL = '/static/'
# 生产环境用 collectstatic 命令收集所有静态文件到此目录
STATIC_ROOT = BASE_DIR / 'staticfiles'
# 媒体文件(用户上传)需要文件系统存储
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
关于 STATICFILES_DIRS,它告诉 Django 去哪里找额外的静态文件:
STATICFILES_DIRS = [
BASE_DIR / 'static', # 项目级别 static 文件夹
]
运行 python manage.py collectstatic 前请确保 STATIC_ROOT 路径正确且未被版本控制。
国际化与本地化
LANGUAGE_CODE = 'zh-hans' # 简体中文
TIME_ZONE = 'Asia/Shanghai' # 中国标准时间
USE_I18N = True # 启用国际化
USE_L10N = True # 本地化格式(Django3+已合并到USE_I18N)
USE_TZ = True # 启用时区支持,数据库存储UTC时间
USE_TZ = True 是强烈推荐的实践,Django 在内部使用 UTC,通过模板过滤器或用户时区转换展示给终端用户。
环境驱动的配置分离
在实际项目中,一套配置显然无法满足本地开发、测试、预发布、生产等多种环境。通常有三种主流实现方式。
方式一:多设置文件(推荐)
创建 settings/ 包,替换原来的 settings.py 模块:
myproject/
├── settings/
│ ├── __init__.py
│ ├── base.py # 公共配置
│ ├── development.py # 开发环境
│ ├── production.py # 生产环境
│ └── local.py # 本地敏感配置(不提交)
└── manage.py
base.py 包含所有环境通用的配置,然后其他文件继承它:
# settings/base.py
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent.parent
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'dev-key')
DEBUG = False
ALLOWED_HOSTS = []
INSTALLED_APPS = [
# ... 所有应用
]
development.py:
from .base import *
DEBUG = True
ALLOWED_HOSTS = ['*']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
production.py:
from .base import *
DEBUG = False
ALLOWED_HOSTS = ['your-domain.com']
DATABASES = {
# 从环境变量加载生产数据库
}
启动时指定设置模块:
# 开发
python manage.py runserver --settings=myproject.settings.development
# 生产(通过环境变量可以避免每次输入)
export DJANGO_SETTINGS_MODULE=myproject.settings.production
或者直接在 manage.py 和 wsgi.py 中读取环境变量 DJANGO_SETTINGS_MODULE 来动态切换。
进阶:使用 Python 的 os.environ.setdefault 在管理脚本中设置默认值:
# manage.py 顶部
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings.development')
生产环境通过设置系统环境变量覆盖即可。
方式二:单一文件 + 条件判断
在 settings.py 开头通过环境变量或主机名判断环境,不推荐大型项目使用:
import os
ENVIRONMENT = os.environ.get('ENVIRONMENT', 'development')
if ENVIRONMENT == 'production':
DEBUG = False
ALLOWED_HOSTS = ['生产域名']
else:
DEBUG = True
ALLOWED_HOSTS = ['*']
这种方式随着配置量增加会变得难以维护,仅适合非常简单的小项目。
方式三:使用 django-environ 库
django-environ 是遵循 12-Factor 应用原则的流行配置库,支持从环境变量和 .env 文件读取配置,并提供类型转换。
安装:pip install django-environ
在 settings.py 中:
import environ
from pathlib import Path
env = environ.Env(
DEBUG=(bool, False)
)
BASE_DIR = Path(__file__).resolve().parent.parent
# 读取 .env 文件(如果存在)
environ.Env.read_env(BASE_DIR / '.env')
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG')
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[])
DATABASES = {
'default': env.db('DATABASE_URL', default='sqlite:///db.sqlite3')
}
.env 文件示例:
SECRET_KEY=your-secret-key
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
DATABASE_URL=postgres://user:password@localhost:5432/mydb
这种方式配置集中、清晰,适合大多数项目,并且非常方便管理不同环境。
敏感信息与安全最佳实践
1. 永远不将敏感信息提交到版本控制
确保 .gitignore 包含:
.env
*.local
*.sqlite3
settings/local.py
2. 安全相关配置项
生产环境需要启用以下安全设置:
CSRF_COOKIE_SECURE = True # 仅通过 HTTPS 发送 CSRF Cookie
SESSION_COOKIE_SECURE = True # 仅通过 HTTPS 发送会话 Cookie
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 31536000 # 一年,启用 HSTS
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_SSL_REDIRECT = True # HTTP 自动跳转 HTTPS
X_FRAME_OPTIONS = 'DENY'
SESSION_COOKIE_HTTPONLY = True # 防止 JS 读取 session cookie
3. 日志与错误报告
生产环境 DEBUG=False 时需要适当配置日志和错误发送:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'ERROR',
'class': 'logging.FileHandler',
'filename': BASE_DIR / 'logs' / 'errors.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'ERROR',
'propagate': True,
},
},
}
同时设置 ADMINS 和 MANAGERS 可以接收服务器错误邮件(需要配置邮件后端):
ADMINS = [('Your Name', 'admin@example.com')]
实际项目配置检查清单
部署前请逐项核对:
-
DEBUG = False -
SECRET_KEY从环境变量获取,且足够随机 -
ALLOWED_HOSTS包含确切域名,不使用通配符* - 所有安全中间件已启用(
django.middleware.security.SecurityMiddleware) - 数据库使用强密码,不使用默认端口和演示数据
- 静态文件已
collectstatic,由 Web 服务器直接服务 - HTTPS 已配置,
SECURE_SSL_REDIRECT和 HSTS 生效 - 敏感信息均通过环境变量或专用密钥管理服务提供
- 日志记录已就绪,且不记录敏感信息
- 第三方包(如 celery、redis)的配置也已分离环境
总结
掌握 Django 配置的关键在于:环境分离、敏感信息外部化、安全性目标清晰。从简单的单一文件开始,逐步过渡到多文件结构或 django-environ,将使你的项目更容易维护、部署和安全审核。配置本身不是一次性的任务,应随着项目成长和环境变化持续优化。
请务必记住:生产环境的每一个疏忽都可能造成严重后果。养成良好的配置习惯,从今天开始!