Django-settings详解
这篇讲什么
settings.py能写的键一共 146 个(本机 Django 5.2.19 的django/conf/global_settings.py现读,不是抄来的数),这篇先讲清「这些键从哪来、默认值怎么查、改了为什么不生效」,再挑最常碰的四十来个逐条实测,最后给一张 146 条的速查表。- 只查某个键的默认值,直接跳「146 条速查表」;正在排「改了 settings 没反应」,先看「改了为什么不生效」。
- 所有输出都是本机跑出来的(中文 Windows + Python 3.14.10 + Django 5.2.19),报错原文照抄不改字;涉及数据库、邮件、真实域名的部分只做本地沙箱验证,没连任何线上环境。
settings 从哪里来
-
三层覆盖关系,读源码就一目了然:
django/conf/__init__.py 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
class LazySettings(LazyObject):
def _setup(self, name=None):
"""
Load the settings module pointed to by the environment variable. This
is used the first time settings are needed, if the user hasn't
configured settings manually.
"""
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
if not settings_module:
desc = ("setting %s" % name) if name else "settings"
raise ImproperlyConfigured(
"Requested %s, but settings are not configured. "
"You must either define the environment variable %s "
"or call settings.configure() before accessing settings."
% (desc, ENVIRONMENT_VARIABLE)
)
self._wrapped = Settings(settings_module)- 取值优先级:
settings.configure()传进来的 > 你的 settings 模块 >global_settings.py里的同名默认值。global_settings是兜底,你没写的键都从它拿。 - 模块头部注释也写明了这条路径(实测生成的
settings.py第 13~17 行):https://docs.djangoproject.com/en/5.2/topics/settings/与.../ref/settings/。
- 取值优先级:
-
想知道「某个键现在是什么值、默认值是什么」,官方给了现成命令:
1
2
3python manage.py diffsettings # 只列与内置默认不同的行
python manage.py diffsettings --all # 列全部(见下面的编码坑)
python manage.py diffsettings --output unified # 用 -/+ 显示差异实测三种输出长这样(同一个刚生成的项目):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18$ manage.py diffsettings
AUTH_PASSWORD_VALIDATORS = [{'NAME': '...UserAttributeSimilarityValidator'}, {'NAME': '...MinimumLengthValidator'}, ...]
BASE_DIR = WindowsPath('E:/Desktop/Test/settings-probe/proj') ###
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': WindowsPath('.../db.sqlite3'), 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, ...}}
DEBUG = True
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
...
MY_OWN_KEY = 42 ###
行数 15
$ manage.py diffsettings --output unified
- AUTH_PASSWORD_VALIDATORS = []
+ AUTH_PASSWORD_VALIDATORS = [{'NAME': '...UserAttributeSimilarityValidator'}, ...]
+ BASE_DIR = WindowsPath('E:/Desktop/Test/settings-probe/proj')
- DEBUG = False
+ DEBUG = True
+ MY_OWN_KEY = 42
行数 26###的含义要分清:默认模式下行尾带###的是「这个键在 Django 内置默认里根本不存在」,也就是你自己加的键(实测BASE_DIR、ROOT_URLCONF、WSGI_APPLICATION、MY_OWN_KEY都带它);没带###的行是「键是内置的,但值和你没改时不一样」。--all会把 146 个键全打出来(实测 150 行:135 行以###开头,表示「这项还是内置默认值」;4 行行尾带###,表示「这个键内置默认里没有」,即自定义键;剩下 11 行是你改过的)。
-
不想跑命令也可以直接读那个模块:
manage.py shell 1
2
3
4
5
6from django.conf import global_settings as g
len([k for k in dir(g) if k.isupper()]) # 146
g.SESSION_COOKIE_AGE # 1209600(两周)
g.CSRF_COOKIE_AGE # 31449600(一年)
g.DEFAULT_AUTO_FIELD # 'django.db.models.AutoField'
g.STORAGES.keys() # dict_keys(['default', 'staticfiles'])- 注意最后一组:
global_settings.DEFAULT_AUTO_FIELD是AutoField,而startproject生成的settings.py里写的是BigAutoField——「Django 的默认值」和「模板给你的值」是两回事,新项目里是后者。
- 注意最后一组:
改了为什么不生效
-
settings 是懒加载的:
import django不会读你的配置文件,第一次访问某个键才去 import。实测:1
2
3
4读之前 settings.configured -> False
读 settings.DEBUG 之后 -> True
type(settings) -> LazySettings
type(settings._wrapped) -> Settingsconfigured是 property 不是方法,写成settings.configured()实测报TypeError: 'bool' object is not callable。
-
没配置就读、又没设环境变量,报的是这段(实测原文):
1
django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
-
写一个 Django 不认识的键不会报错,它只是没人读而已。实测在
settings.py末尾加MY_OWN_KEY = 42后:1
2
3$ python manage.py check
System check identified no issues (0 silenced).
settings.MY_OWN_KEY = 42-
反过来,读一个不存在的键是
AttributeError(实测):1
AttributeError: 'Settings' object has no attribute 'NOT_A_REAL_KEY'
-
所以「键名拼错」和「这个版本没有这个键」都表现为静默无效,
diffsettings里看到它带###就说明 Django 不认识它——这是排查这类问题最快的办法。
-
-
列表和字典类设置是整体替换,不是追加(官方在 Core Settings 页专门警告过)。实测只写一个 finder:
settings.py 1
STATICFILES_FINDERS = ["django.contrib.staticfiles.finders.AppDirectoriesFinder"]
1
2
3global STATICFILES_FINDERS: [...FileSystemFinder, ...AppDirectoriesFinder]
只写 AppDirectoriesFinder 后实际启用的 finder: ['AppDirectoriesFinder']
FileSystemFinder 还在吗: False-
同理
INSTALLED_APPS、MIDDLEWARE、TEMPLATES、PASSWORD_HASHERS都是这样;要保留默认项就自己抄全,或者用「先取默认再拼」的写法:settings.py 1
2
3from django.conf import global_settings
STATICFILES_FINDERS = [*global_settings.STATICFILES_FINDERS, "myapp.finders.MyFinder"]
-
-
override_settings改不动已经加载的东西。实测两件事:1
2进程内 override_settings(USE_I18N=False) + LANGUAGE_CODE=zh-hans -> 后台登录页仍是「用户名/密码/登录」
新进程里 USE_I18N=False + LANGUAGE_CODE=zh-hans -> 同一页面变回 Username / Password / Log in- 结论:翻译表在 setup 时就装好了,
override_settings不会重新加载。测试里要验USE_I18N、LANGUAGES这类行为,得另起进程或用settings.configure()从头配。
- 结论:翻译表在 setup 时就装好了,
-
DJANGO_SETTINGS_MODULE与环境变量谁赢:命令行--settings赢。实测:1
2
3
4$ python manage.py check --settings proj.settings_alt
System check identified no issues (0 silenced).
最终生效的模块: proj.settings_alt
ALLOWED_HOSTS(alt 里改过): ['alt.example']- 环境变量
DJANGO_SETTINGS_MODULE只在没给--settings时起作用;manage.py顶部那行os.environ.setdefault(...)之所以是setdefault,就是为了允许外面覆盖。
- 环境变量
-
一个进程只能
configure()一次(脚本化跑探针时最容易撞):1
2第一次 configure 成功
第二次 configure -> RuntimeError: Settings already configured.- 所以要对比两套配置,就得起两个子进程,别在一个进程里来回 configure。
生成的 settings 逐行
-
django-admin startproject proj生成的settings.py一共 123 行,下面按块过一遍(引号风格取决于本机装没装black:本机装了,所以是双引号;没装就是模板里的单引号)。settings.py 1
2
3from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parentBASE_DIR不是配置项(diffsettings里它带###就是证据),是模板给你算好的路径对象;因为是pathlib.Path,后面可以直接BASE_DIR / "db.sqlite3"。- 老写法
os.path.join(BASE_DIR, "templates")也能用,但要先import os。
settings.py 1
2
3
4
5
6
7# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-ck2a2sl&c8wuq8kvly_#)45hr_*6-yx*-*gujs__2_cbko01#a"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []-
SECRET_KEY是签名与加密的根钥匙(会话签名、CSRF、signing、密码重置 token 都用它)。空着会在真正用到时报(实测):1
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
-
生成值带
django-insecure-前缀是官方故意留的提醒;生产环境别写进代码库,走环境变量(password之类的真实值也不要出现在文件里)。 -
SECRET_KEY_FALLBACKS(5.1 起)是给轮换密钥用的:新密钥上线时把旧密钥放进这个列表,旧签名还能验,实测配置能读:settings.py 1
SECRET_KEY_FALLBACKS = ["old-secret-key"]
-
DEBUG决定错误页、静态文件由谁服务、模板是否缓存,见下面「基础与调试」。 -
ALLOWED_HOSTS空列表 +DEBUG=True时runserver只放过本机域名;一旦DEBUG=False就全拦(实测):1
2
3Invalid HTTP_HOST header: 'testserver'. You may need to add 'testserver' to ALLOWED_HOSTS.
django.core.exceptions.DisallowedHost: Invalid HTTP_HOST header: 'testserver'. ...
状态: 400 -
补上
ALLOWED_HOSTS = ["testserver"]后同一请求变 404(说明 host 校验过了,只是没这个路由)。
settings.py 1
2
3
4
5
6
7
8INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]INSTALLED_APPS的顺序不是装饰:模板与静态文件按这个顺序找,谁在前谁的赢。《Django-站点管理》里django-admin-interface必须排在django.contrib.admin之前就是这个原因(实测放后面时主题完全不生效,页面 7232 字节 vs 放对 20546 字节)。django.contrib.sites不在默认列表里,但SITE_ID相关的功能(contrib.sites、部分第三方包)会要它。
settings.py 1
2
3
4
5
6
7
8
9MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]- 顺序即请求进入顺序、响应返回顺序(逆序)。细节见《Django-中间件》。
SecurityMiddleware放最前是因为SECURE_*那批响应头要在最早加上;CommonMiddleware要在CsrfViewMiddleware之前,APPEND_SLASH的 301 才不会被 CSRF 先拦掉。
settings.py 1
2ROOT_URLCONF = "proj.urls"
WSGI_APPLICATION = "proj.wsgi.application"- 两个都是「点路径字符串」,Django 在需要时才
importlib.import_module。WSGI_APPLICATION被 gunicorn/uWSGI 引用,见《Django-应用水平扩展》。
settings.py 1
2
3
4
5
6
7
8
9
10
11
12
13
14TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]DIRS空的话项目级模板目录找不到,TEMPLATES是列表,多引擎共存时按顺序命中;APP_DIRS: True才会在每个 app 的templates/子目录里找。- 子键写错比顶层键写错更常见:
context_processors少写request那项,{% csrf_token %}和 admin 都会出问题;少写messages则messages模板变量为空。细节见《Django-模板》。
settings.py 1
2
3
4
5
6DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}-
MySQL/PostgreSQL 的完整写法与驱动选型见《Django-基本入门》《PostgreSQL入门》;
DATABASES的子键(CONN_MAX_AGE、ATOMIC_REQUESTS、OPTIONS、TIME_ZONE、TEST)实测在diffsettings里全部展开,形如:1
2
3'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'CONN_HEALTH_CHECKS': False,
'OPTIONS': {}, 'TIME_ZONE': None, 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '',
'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None} -
CONN_MAX_AGE默认 0(每个请求重连),生产常设 60;PASSWORD走环境变量,不要把明文写进代码。
settings.py 1
2
3
4
5
6LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
STATIC_URL = "static/"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"-
这几行的实测行为见下面「国际化与格式」和「基础与调试」。
-
AUTH_PASSWORD_VALIDATORS默认给了四个校验器(长度、常见密码、纯数字、与用户属性相似),实测把最小长度改成 12 后:1
2
3'short1' 被拦: ['This password is too short. It must contain at least 12 characters.', 'This password is too common.']
'password' 被拦: ['This password is too short. It must contain at least 12 characters.', 'This password is too common.']
'Zhang2026!ok' 通过- 校验只在
validate_password()/UserCreationForm/ admin 建用户时触发,直接user.set_password()不会拦,这点见《Django-站点管理》的密码一节。
- 校验只在
-
编码坑(中文 Windows 特有):
diffsettings --all在本机直接崩,因为LANGUAGES里有非 GBK 字符(如Åland):1
UnicodeEncodeError: 'gbk' codec can't encode character '\xe5' in position 5297: illegal multibyte sequence
- 加
PYTHONIOENCODING=utf-8再跑就正常(实测 150 行输出)。同理适用于showmigrations、sqlmigrate这类会打印大量内置值的命令。
- 加
核心配置实测
- 下面按官方分组过一遍最常碰的键。每条给「默认值 → 改完看到什么」,实测输出都在本机拿的;已经写过专篇的细节只留一句指路,不重复展开。
基础与调试
-
DEBUG(默认False,模板给True):开着才有技术性的 404/500 页、才由 Django 自己服务静态文件、模板才每次重新解析。生产必须关,理由见《Django-生产环境中的安全》。 -
INTERNAL_IPS(默认[]):DEBUG=True时django.debug相关能力与第三方调试面板只对列表里的客户端 IP 开,本机一般写["127.0.0.1"];django-debug-toolbar也读它,见《Django-常用插件》。 -
ADMINS/MANAGERS(默认[]):元组列表[(姓名, 邮箱)]。DEBUG=False时 500 会发邮件给ADMINS,404 发给MANAGERS;发件人是SERVER_EMAIL。实测配置可读:1
ADMINS 可读 -> ('老板', 'boss@example.com')
-
DEFAULT_EXCEPTION_REPORTER/DEFAULT_EXCEPTION_REPORTER_FILTER:报错的组装者与「哪些字段名要屏蔽」。SECRET_KEY、password这类是被过滤的默认名单,日志脱敏见《Django-接入监控告警》。 -
DEBUG_PROPAGATE_EXCEPTIONS(默认False):设True后异常直接穿透中间件抛出来,测试里想assertRaises就用它。 -
SILENCED_SYSTEM_CHECKS(默认[]):按检查 ID 静默,比如["models.W042"]。能静默不等于该静默,先看那条检查说什么。
安全响应头与跳转
-
实测这一组响应头,全部用
override_settings+ 测试客户端拿的:1
2
3
4
5
6
7
8
9SECURE_SSL_REDIRECT=True http 请求 301 / https 请求 200
SECURE_REDIRECT_EXEMPT=[r"^post/$"] 该路径不跳,http 直接 200
SECURE_HSTS_SECONDS=3600 + 两个子开关
Strict-Transport-Security: max-age=3600; includeSubDomains; preload
且只在 https 响应里出现,http 响应为空
SECURE_CONTENT_TYPE_NOSNIFF=True X-Content-Type-Options: nosniff
SECURE_CROSS_ORIGIN_OPENER_POLICY Cross-Origin-Opener-Policy(默认 same-origin)
X_FRAME_OPTIONS=DENY(默认值) X-Frame-Options: DENY;实测改 SAMEORIGIN 也生效
SECURE_REFERRER_POLICY Referrer-Policy,默认已是 same-origin -
SECURE_PROXY_SSL_HEADER(默认None):站在 Nginx 后面时必须配,否则 Django 看到的是 http,SECURE_SSL_REDIRECT会和代理互相 301 死循环。实测配上("HTTP_X_FORWARDED_PROTO", "https")后带该头的请求直接 200。 -
USE_X_FORWARDED_HOST/USE_X_FORWARDED_PORT(默认False):代理改写 Host/Port 时才打开;开了就要保证代理真的覆盖这两个头,否则ALLOWED_HOSTS校验会被伪造头绕过。 -
DISALLOWED_USER_AGENTS(默认[]):放正则列表,命中直接 403。实测[re.compile("BadBot")]时User-Agent: BadBot/1返回 403。 -
IGNORABLE_404_URLS(默认[]):这些 URL 的 404 不给MANAGERS发邮件,典型值是/favicon.ico和扫描器路径。 -
APPEND_SLASH(默认True):路径少写斜杠时 301 补上。实测对比很干净:1
2APPEND_SLASH=True GET /post -> 301,Location: /post/
APPEND_SLASH=False GET /post -> 404 -
PREPEND_WWW(默认False):example.com跳www.example.com。实测开True后对example.com的请求返回 301。 -
FORCE_SCRIPT_NAME(默认None):应用挂在子路径(/mount/point/)下、代理又剥掉了前缀时用它固定get_script_prefix()。实测设/mount/后django.get_script_prefix()就是/mount/。
CSRF
-
默认下发
csrftokencookie,实测属性是max-age=31449600(一年)、httponly空(也就是 False)、samesite=Lax、secure空。逐项改的实测结果:1
2
3
4
5CSRF_COOKIE_HTTPONLY=True -> httponly=True(注意:前端 JS 就取不到 token 了,fetch 方案要改)
CSRF_COOKIE_NAME="mycsrf" -> cookie 名变 mycsrf
CSRF_COOKIE_AGE=120 -> max-age=120
CSRF_COOKIE_SECURE=True -> secure=True(只在 https 下发)
CSRF_COOKIE_SAMESITE="Strict" -> samesite=Strict -
CSRF_USE_SESSIONS=True:token 改存 session,实测响应里不再下发csrftokencookie,但表单里仍有csrfmiddlewaretoken隐藏域。代价是每个请求都要读 session。 -
CSRF_TRUSTED_ORIGINS(默认[]):跨域前端 + 同域后端最容易漏的一项。实测:1
2
3CSRF_TRUSTED_ORIGINS=["http://ok.example"]
Origin: http://ok.example -> 200
Origin: http://evil.example -> 403 -
CSRF_COOKIE_DOMAIN/CSRF_COOKIE_PATH:多子域共享 token 时才动,配错的表现是「同域能提交、子域 403」。 -
CSRF_HEADER_NAME(默认HTTP_X_CSRF_TOKEN_NAME对应的X-CSRFToken):前端换自定义头名时改它。 -
CSRF_FAILURE_VIEW(默认django.views.csrf.csrf_failure):想自定义 403 页面就指到自己的视图。
会话
-
SESSION_ENGINE五种后端实测都能 round-trip(写一个键再按 session_key 读回来):1
db / cache / cached_db / file / signed_cookies -> 全部 OK
- 选法:单机开发用默认
db;多进程/多机用cache或cached_db(Redis 配置见《Django-缓存》);signed_cookies把数据放进 cookie 本身,体积和敏感信息都受限。
- 选法:单机开发用默认
-
cookie 属性实测:默认
sessionid是max-age=1209600(两周)、httponly=True、samesite=Lax、secure空。逐项:1
2
3
4
5
6SESSION_COOKIE_AGE=60 max-age=60,expires 也跟着推
SESSION_EXPIRE_AT_BROWSER_CLOSE=True max-age 与 expires 都变空(浏览器会话 cookie)
SESSION_COOKIE_AGE=60 + EXPIRE_AT_BROWSER 后者优先,仍是会话 cookie
SESSION_COOKIE_NAME="mysess" cookie 名变 mysess
SESSION_COOKIE_HTTPONLY=False httponly 变空
SESSION_COOKIE_SAMESITE="None" + SECURE=True samesite=None 且 secure=TrueSameSite=None必须配SESSION_COOKIE_SECURE=True,否则浏览器会丢弃该 cookie——这是前后端分离项目最常见的「登录后刷新又掉线」原因。
-
SESSION_SAVE_EVERY_REQUEST(默认False):实测先建 session 再请求一个完全不碰 session 的视图,True时每次响应都重发sessionid(等于滑动过期),False时不重发。 -
SESSION_SERIALIZER(默认 JSON):换成 pickle 会引入反序列化风险,别动。 -
SESSION_CACHE_ALIAS/SESSION_FILE_PATH:分别指定会话用哪个缓存别名、file后端存哪个目录(默认系统临时目录,生产建议明确写)。
国际化与格式
-
LANGUAGE_CODE(默认en-us)改成zh-hans后,后台登录页文案实测跟着变:1
2en-us label: ['Username:', 'Password:'] value: ['/admin/', 'Log in']
zh-hans label: ['用户名:', '密码:'] value: ['/admin/', '登录'] -
USE_I18N=False会关掉翻译,但实测在已启动的进程里用override_settings改它不生效(页面仍是中文),新进程里才变回英文:1
新进程 USE_I18N=False + LANGUAGE_CODE=zh-hans -> labels=['Username:', 'Password:'] values=['Log in']
-
LANGUAGES/LANGUAGE_COOKIE_*/LOCALE_PATHS:前者限定可切换语言,中间那组控制语言偏好 cookie,LOCALE_PATHS放项目自己的.po/.mo。多语言切换的实现见《Django-模板》。 -
TIME_ZONE(默认UTC)与USE_TZ(默认True)实测:1
2TIME_ZONE=Asia/Shanghai 时,UTC 的 2026-11-05 00:00 经 timezone.localtime -> 2026-11-05 08:00:00+08:00
USE_TZ=False 时 timezone.now().tzinfo -> None- 也就是说库里存 UTC、显示按
TIME_ZONE。连 MySQL 时要小心会话时区让Now()写进时间列偏 8 小时,这条实测在《Django-环境搭建与版本迁移》里记过。
- 也就是说库里存 UTC、显示按
-
数字与日期格式有一层优先级,实测很容易踩:
1
2
3
4
5THOUSAND_SEPARATOR="#" + use_l10n=True + en -> 1,234,567.5 (语言包赢)
THOUSAND_SEPARATOR="#" + use_l10n=False -> 1234567.5 (连分组都没了)
zh-hans 语言包 + use_l10n=True -> 1234567.5
DECIMAL_SEPARATOR="," + use_l10n=False -> 1234567,5
DECIMAL_SEPARATOR="," + use_l10n=True -> 1,234,567.5- 结论:
use_l10n=True时语言包优先于 settings,use_l10n=False才轮到 settings 里的DECIMAL_SEPARATOR;而USE_THOUSAND_SEPARATOR的分组在use_l10n=False下并不生效。模板里{% localize %}、l10n模板标签与这些行为对应。 - 自定义格式走
FORMAT_MODULE_PATH(指向一个含en/、zh_Hans/之类包的目录),或者显式DATE_FORMAT之类:实测DATE_FORMAT="Y年m月d日"配formats.date_format(d, "DATE_FORMAT", use_l10n=False)得到2026年11月05日。
- 结论:
-
FIRST_DAY_OF_WEEK(默认0)由语言包给值:实测zh-hans下formats.get_format("FIRST_DAY_OF_WEEK", use_l10n=True)是1。日历类组件要按它决定周起点。
静态文件与存储
-
STATIC_URL(模板给static/):只是 URL 前缀,不负责找文件;STATIC_ROOT是collectstatic的输出目录,两者都写进settings.py才完整。 -
STATICFILES_DIRS(默认[]):项目级静态目录,写法BASE_DIR / "static"。 -
STATICFILES_FINDERS:见「改了为什么不生效」,整体替换,实测漏写FileSystemFinder后STATICFILES_DIRS就失效。 -
STORAGES(4.2 起取代DEFAULT_FILE_STORAGE/STATICFILES_STORAGE):两个别名default与staticfiles,实测:1
2global STORAGES -> {'default': {...FileSystemStorage}, 'staticfiles': {...StaticFilesStorage}}
把 staticfiles 换成 ManifestStaticFilesStorage 后 staticfiles_storage 类型 -> ManifestStaticFilesStorage- 换 Manifest 就必须先
collectstatic,模板里也一律用{% static %},否则 hash 名对不上直接 404(这条实测在《Django-生产环境要注意哪些事项》里)。
- 换 Manifest 就必须先
-
MEDIA_URL/MEDIA_ROOT:用户上传文件的 URL 前缀与磁盘目录,DEBUG=False时 Django 不负责服务它,要交给 Nginx,见《Django-上传文件》。 -
FILE_UPLOAD_HANDLERS/FILE_UPLOAD_MAX_MEMORY_SIZE/FILE_UPLOAD_TEMP_DIR/FILE_UPLOAD_PERMISSIONS/FILE_UPLOAD_DIRECTORY_PERMISSIONS:上传走「内存 → 临时文件」两级,阈值由FILE_UPLOAD_MAX_MEMORY_SIZE(默认 2.5 MB)决定;实测把它压到 10 字节后,200 字节的上传请求直接 400。
请求体上限
-
三个
DATA_UPLOAD_*是 DoS 防护,实测超限都是 400(不是 413):1
2
3DATA_UPLOAD_MAX_NUMBER_FIELDS=2,POST 三个字段 -> 400(默认 1000)
DATA_UPLOAD_MAX_MEMORY_SIZE=10,body 500 字节 -> 400(默认 2.5 MB)
DATA_UPLOAD_MAX_NUMBER_FILES(默认 1000) -> 一次请求的文件数上限- 表单字段多的后台(几百列的导入页)常撞
NUMBER_FIELDS,报错原文是SuspiciousOperation: Too many GET/POST parameters,改大它就行,别误判成攻击。
- 表单字段多的后台(几百列的导入页)常撞
邮件
-
EMAIL_BACKEND决定邮件去哪,开发期三种最常用:locmem(进django.core.mail.outbox,实测能断言)、console(打到 stdout)、filebased(落盘.msg文件,实测生成 1 个)。 -
DEFAULT_FROM_EMAIL与EMAIL_SUBJECT_PREFIX实测直接体现在发出去的信上:1
2DEFAULT_FROM_EMAIL="noreply@example.com" + EMAIL_SUBJECT_PREFIX="[笔记] "
-> from_email = noreply@example.com | subject = [笔记] 标题 -
SERVER_EMAIL(默认root@localhost)是系统错误邮件(500/404 给 ADMINS/MANAGERS 的那些)的发件人,很多邮箱会因这个假地址直接拒信。 -
EMAIL_HOST/EMAIL_PORT/EMAIL_HOST_USER/EMAIL_HOST_PASSWORD/EMAIL_USE_TLS/EMAIL_USE_SSL/EMAIL_SSL_CERTFILE/EMAIL_SSL_KEYFILE/EMAIL_TIMEOUT:SMTP 连接参数。password走环境变量,不要把明文写进代码;EMAIL_USE_TLS(STARTTLS,常见 587)和EMAIL_USE_SSL(隐式 TLS,常见 465)不要同时开。发送流程与附件写法见《Django-发送邮件》。 -
EMAIL_USE_LOCALTIME(默认False):邮件头里的时间是否用本地时区。
认证与密码
-
AUTH_USER_MODEL(默认auth.User):要自定义用户模型必须在第一次 migrate 前改,之后改要处理已有表,细节见《Django-模型》。 -
AUTHENTICATION_BACKENDS(默认ModelBackend):认证后端链,按顺序试;接 LDAP/OAuth 时往里加。 -
AUTH_PASSWORD_VALIDATORS:实测四个默认校验器 + 自定义min_length的效果见「生成的 settings 逐行」。 -
PASSWORD_HASHERS:列表首位就是新密码用的算法。实测临时换成 MD5 后:1
2PASSWORD_HASHERS=["django.contrib.auth.hashers.MD5PasswordHasher"]
user.set_password("abc") -> 'md5$...$...'(测试跑得快靠这个)- 老密码不会自动升级,登录成功时 Django 按列表顺序识别并升级,别把旧算法从列表里删掉。
-
PASSWORD_RESET_TIMEOUT(默认 2592000 秒,即 3 天):重置 token 的有效期。 -
LOGIN_URL/LOGIN_REDIRECT_URL/LOGOUT_REDIRECT_URL:实测未登录访问/admin/返回 302 且Location指向登录页。@login_required读LOGIN_URL,admin 用自己的。
数据库与缓存
-
DATABASES的完整子键在diffsettings里能一次看全(实测展开见「生成的 settings 逐行」)。CONN_MAX_AGE默认 0,CONN_HEALTH_CHECKS默认False,长连接池场景两个一起配。 -
DATABASE_ROUTERS(默认[]):多库读写分离/分库的路由类列表。 -
DEFAULT_AUTO_FIELD:实测不配时check报:1
2autocheckapp.Item: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
HINT: Configure the DEFAULT_AUTO_FIELD setting or the AutocheckappConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.- 配上
BigAutoField后System check identified no issues (0 silenced).。优先级是 AppConfig 的default_auto_field> settings 的DEFAULT_AUTO_FIELD> 内置AutoField。
- 配上
-
CACHES:默认只有一个default,后端是LocMemCache(进程内,多进程不共享,实测踩过)。Redis 后端的写法与失效策略见《Django-缓存》。 -
CACHE_MIDDLEWARE_ALIAS/_SECONDS/_KEY_PREFIX:UpdateCacheMiddleware用哪份缓存、默认 TTL、key 前缀。 -
TEST_RUNNER(默认DiscoverRunner)、TEST_NON_SERIALIZED_APPS、FIXTURE_DIRS、MIGRATION_MODULES:测试与迁移相关的四个,日常改得少,MIGRATION_MODULES还能指向None来禁用某 app 的迁移。 -
DEFAULT_TABLESPACE/DEFAULT_INDEX_TABLESPACE:非默认表空间才需要,本机未验证(默认None)。
模板与表单
-
TEMPLATES是列表,每个引擎的OPTIONS里context_processors、debug、loaders、string_if_invalid都能配;实测把string_if_invalid设成标记串后,模板里取不到的变量会直接把标记渲染出来,排查变量名拼错很好用(见《Django-模板》)。 -
FORM_RENDERER(默认DjangoTemplates,走django/forms/templates):实测换成DjangoDivFormRenderer后,str(form)的外层从<ul>变<div>:1
FORM_RENDERER="django.forms.renderers.DjangoDivFormRenderer" -> <div>...(无 <ul>)
-
FORMS_URLFIELD_ASSUME_HTTPS(默认False):URLField对 scheme 的处理开关,5.x 过渡项, transitional 用。 -
MESSAGE_STORAGE(默认FallbackStorage,先 session 后 cookie):实测改成CookieStorage后配置值直接可读,无 session 的项目常用它。 -
ABSOLUTE_URL_OVERRIDES(默认{}):不给模型写get_absolute_url,改在这里按app_label.ModelName配函数。
日志
LOGGING_CONFIG(默认logging.config.dictConfig)与LOGGING:LOGGING是标准 dict 配置,disable_existing_loggers忘写会静默掉 Django 自己的 logger。写法与落盘见《Django-生产环境要注意哪些事项》。
146 条速查表
- 默认值这一列全部由
django.conf.global_settings(Django 5.2.19)现读,不是抄文档;列表和字典只给项数与首项/键名。 - 用法列只写「这个键管什么」,具体行为与实测在上面「核心配置实测」一节。
| 键 | 类型 | 默认值(本机现读) | 一句话用途 |
|---|---|---|---|
ABSOLUTE_URL_OVERRIDES |
dict | {}(空字典) | 不给模型写 get_absolute_url,按 app_label.ModelName 配函数 |
ADMINS |
list | [](空列表) | 500 错误邮件的收件人列表 |
ALLOWED_HOSTS |
list | [](空列表) | 允许的 Host 头(域名白名单) |
APPEND_SLASH |
bool | True | 路径少写斜杠时是否 301 补上 |
AUTHENTICATION_BACKENDS |
list | 1 项,首项 'django.contrib.auth.backends.Mode… | 认证后端链,按顺序试 |
AUTH_PASSWORD_VALIDATORS |
list | [](空列表) | 密码强度校验器列表 |
AUTH_USER_MODEL |
str | ‘auth.User’ | 自定义用户模型,首次 migrate 前定死 |
CACHES |
dict | 1 键:default | 缓存后端与别名 |
CACHE_MIDDLEWARE_ALIAS |
str | ‘default’ | 缓存中间件用哪个缓存别名 |
CACHE_MIDDLEWARE_KEY_PREFIX |
str | ‘’ | 缓存中间件的 key 前缀 |
CACHE_MIDDLEWARE_SECONDS |
int | 600 | 缓存中间件的默认 TTL |
CSRF_COOKIE_AGE |
int | 31449600 | csrftoken cookie 有效期 |
CSRF_COOKIE_DOMAIN |
NoneType | None | csrftoken 的域 |
CSRF_COOKIE_HTTPONLY |
bool | False | csrftoken 是否禁止 JS 读取 |
CSRF_COOKIE_NAME |
str | ‘csrftoken’ | csrftoken 的 cookie 名 |
CSRF_COOKIE_PATH |
str | ‘/’ | csrftoken 的 cookie 路径 |
CSRF_COOKIE_SAMESITE |
str | ‘Lax’ | csrftoken 的 SameSite |
CSRF_COOKIE_SECURE |
bool | False | csrftoken 是否只在 HTTPS 下发 |
CSRF_FAILURE_VIEW |
str | ‘django.views.csrf.csrf_failure’ | CSRF 校验失败时渲染的视图 |
CSRF_HEADER_NAME |
str | ‘HTTP_X_CSRFTOKEN’ | 从哪个请求头读 CSRF token |
CSRF_TRUSTED_ORIGINS |
list | [](空列表) | 可信的 Origin 列表(跨域前端必配) |
CSRF_USE_SESSIONS |
bool | False | CSRF token 改存 session,不发 cookie |
DATABASES |
dict | {}(空字典) | 数据库别名与连接参数 |
DATABASE_ROUTERS |
list | [](空列表) | 多库/读写分离的路由类 |
DATA_UPLOAD_MAX_MEMORY_SIZE |
int | 2621440 | 请求体大小上限(非文件部分) |
DATA_UPLOAD_MAX_NUMBER_FIELDS |
int | 1000 | GET/POST 参数个数上限 |
DATA_UPLOAD_MAX_NUMBER_FILES |
int | 100 | 一次请求的文件数上限 |
DATETIME_FORMAT |
str | ‘N j, Y, P’ | 日期时间的默认显示格式 |
DATETIME_INPUT_FORMATS |
list | 9 项,首项 ‘%Y-%m-%d %H:%M:%S’ | 表单解析日期时间的候选格式 |
DATE_FORMAT |
str | ‘N j, Y’ | 日期的默认显示格式 |
DATE_INPUT_FORMATS |
list | 11 项,首项 ‘%Y-%m-%d’ | 表单解析日期的候选格式 |
DEBUG |
bool | False | 调试模式,生产必须 False |
DEBUG_PROPAGATE_EXCEPTIONS |
bool | False | 让异常穿透中间件,测试断言用 |
DECIMAL_SEPARATOR |
str | ‘.’ | 小数点字符 |
DEFAULT_AUTO_FIELD |
str | ‘django.db.models.AutoField’ | 模型默认自增主键类型 |
DEFAULT_CHARSET |
str | ‘utf-8’ | HTTP 响应的字符集 |
DEFAULT_EXCEPTION_REPORTER |
str | ‘django.views.debug.ExceptionReporter’ | 500 报错的组装者 |
DEFAULT_EXCEPTION_REPORTER_FILTER |
str | 'django.views.debug.SafeExceptionRepo… | 报错里要屏蔽的敏感字段 |
DEFAULT_FROM_EMAIL |
str | ‘webmaster@localhost’ | send_mail 默认发件人 |
DEFAULT_INDEX_TABLESPACE |
str | ‘’ | 建索引的默认表空间 |
DEFAULT_TABLESPACE |
str | ‘’ | 建表的默认表空间 |
DISALLOWED_USER_AGENTS |
list | [](空列表) | 命中的 User-Agent 直接 403 |
EMAIL_BACKEND |
str | 'django.core.mail.backends.smtp.Email… | 邮件后端类(发真信/只收集/落盘) |
EMAIL_HOST |
str | ‘localhost’ | SMTP 服务器地址 |
EMAIL_HOST_PASSWORD |
str | ‘’ | SMTP 密码(走环境变量) |
EMAIL_HOST_USER |
str | ‘’ | SMTP 用户名 |
EMAIL_PORT |
int | 25 | SMTP 端口(25/465/587) |
EMAIL_SSL_CERTFILE |
NoneType | None | SMTPS 客户端证书 |
EMAIL_SSL_KEYFILE |
NoneType | None | SMTPS 客户端私钥 |
EMAIL_SUBJECT_PREFIX |
str | '[Django] ’ | 邮件主题前缀 |
EMAIL_TIMEOUT |
NoneType | None | SMTP 连接超时秒数 |
EMAIL_USE_LOCALTIME |
bool | False | 邮件头时间是否用本地时区 |
EMAIL_USE_SSL |
bool | False | 隐式 TLS(常见 465) |
EMAIL_USE_TLS |
bool | False | STARTTLS(常见 587) |
FILE_UPLOAD_DIRECTORY_PERMISSIONS |
NoneType | None | 上传时新建目录的权限 |
FILE_UPLOAD_HANDLERS |
list | 2 项,首项 'django.core.files.uploadhandler.M… | 上传处理器链(内存/临时文件) |
FILE_UPLOAD_MAX_MEMORY_SIZE |
int | 2621440 | 超过就转临时文件的阈值 |
FILE_UPLOAD_PERMISSIONS |
int | 420 | 上传文件的权限位 |
FILE_UPLOAD_TEMP_DIR |
NoneType | None | 上传临时文件目录 |
FIRST_DAY_OF_WEEK |
int | 0 | 一周的第一天(语言包会给值) |
FIXTURE_DIRS |
list | [](空列表) | 加载测试数据的额外目录 |
FORCE_SCRIPT_NAME |
NoneType | None | 强制 URL 前缀(挂在子路径时) |
FORMAT_MODULE_PATH |
NoneType | None | 自定义格式模块所在的包 |
FORMS_URLFIELD_ASSUME_HTTPS |
bool | False | URLField 是否默认补 https |
FORM_RENDERER |
str | ‘django.forms.renderers.DjangoTemplates’ | 表单渲染器类 |
IGNORABLE_404_URLS |
list | [](空列表) | 这些 URL 的 404 不给 MANAGERS 发邮件 |
INSTALLED_APPS |
list | [](空列表) | 安装的应用(顺序影响模板与静态查找) |
INTERNAL_IPS |
list | [](空列表) | 调试能力只对哪些客户端 IP 开 |
LANGUAGES |
list | 99 项,首项 ‘af’ | 可切换的语言列表 |
LANGUAGES_BIDI |
list | 7 项,首项 ‘he’ | 从右往左书写的语言 |
LANGUAGE_CODE |
str | ‘en-us’ | 默认语言 |
LANGUAGE_COOKIE_AGE |
NoneType | None | 语言偏好 cookie 有效期 |
LANGUAGE_COOKIE_DOMAIN |
NoneType | None | 语言偏好 cookie 的域 |
LANGUAGE_COOKIE_HTTPONLY |
bool | False | 语言偏好 cookie 是否禁 JS 读 |
LANGUAGE_COOKIE_NAME |
str | ‘django_language’ | 语言偏好 cookie 名 |
LANGUAGE_COOKIE_PATH |
str | ‘/’ | 语言偏好 cookie 路径 |
LANGUAGE_COOKIE_SAMESITE |
NoneType | None | 语言偏好 cookie 的 SameSite |
LANGUAGE_COOKIE_SECURE |
bool | False | 语言偏好 cookie 是否仅 HTTPS |
LOCALE_PATHS |
list | [](空列表) | 项目自己的翻译文件目录 |
LOGGING |
dict | {}(空字典) | 日志配置字典 |
LOGGING_CONFIG |
str | ‘logging.config.dictConfig’ | 应用 LOGGING 用的函数 |
LOGIN_REDIRECT_URL |
str | ‘/accounts/profile/’ | 登录后的默认跳转 |
LOGIN_URL |
str | ‘/accounts/login/’ | 未登录时 @login_required 跳哪 |
LOGOUT_REDIRECT_URL |
NoneType | None | 登出后的跳转 |
MANAGERS |
list | [](空列表) | 404 错误邮件的收件人列表 |
MEDIA_ROOT |
str | ‘’ | 用户上传文件的根目录 |
MEDIA_URL |
str | ‘’ | 用户上传文件的 URL 前缀 |
MESSAGE_STORAGE |
str | 'django.contrib.messages.storage.fall… | 消息存储类 |
MIDDLEWARE |
list | [](空列表) | 中间件链(顺序即执行顺序) |
MIGRATION_MODULES |
dict | {}(空字典) | 指定 app 的迁移模块,可为 None 禁用 |
MONTH_DAY_FORMAT |
str | ‘F j’ | 月日格式 |
NUMBER_GROUPING |
int | 0 | 千分位分组长度 |
PASSWORD_HASHERS |
list | 5 项,首项 'django.contrib.auth.hashers.PBKDF… | 密码哈希算法优先级 |
PASSWORD_RESET_TIMEOUT |
int | 259200 | 重置 token 的有效期 |
PREPEND_WWW |
bool | False | 自动跳到 www. 前缀 |
SECRET_KEY |
str | ‘’ | 签名与加密的根钥匙 |
SECRET_KEY_FALLBACKS |
list | [](空列表) | 轮换密钥期间兼容的旧密钥 |
SECURE_CONTENT_TYPE_NOSNIFF |
bool | True | 加 X-Content-Type-Options 头 |
SECURE_CROSS_ORIGIN_OPENER_POLICY |
str | ‘same-origin’ | 加 Cross-Origin-Opener-Policy 头 |
SECURE_HSTS_INCLUDE_SUBDOMAINS |
bool | False | HSTS 是否覆盖子域 |
SECURE_HSTS_PRELOAD |
bool | False | HSTS 是否带 preload 标记 |
SECURE_HSTS_SECONDS |
int | 0 | HSTS 时长(仅 HTTPS 响应出现) |
SECURE_PROXY_SSL_HEADER |
NoneType | None | 认代理传来的协议头 |
SECURE_REDIRECT_EXEMPT |
list | [](空列表) | 这些路径不做 HTTPS 跳转 |
SECURE_REFERRER_POLICY |
str | ‘same-origin’ | Referrer-Policy 头 |
SECURE_SSL_HOST |
NoneType | None | 强制跳转的目标域名 |
SECURE_SSL_REDIRECT |
bool | False | 非 HTTPS 一律 301 |
SERVER_EMAIL |
str | ‘root@localhost’ | 系统错误邮件的发件人 |
SESSION_CACHE_ALIAS |
str | ‘default’ | 会话用哪个缓存别名 |
SESSION_COOKIE_AGE |
int | 1209600 | 会话 cookie 有效期 |
SESSION_COOKIE_DOMAIN |
NoneType | None | 会话 cookie 的域 |
SESSION_COOKIE_HTTPONLY |
bool | True | 会话 cookie 是否禁止 JS 读 |
SESSION_COOKIE_NAME |
str | ‘sessionid’ | 会话 cookie 名 |
SESSION_COOKIE_PATH |
str | ‘/’ | 会话 cookie 路径 |
SESSION_COOKIE_SAMESITE |
str | ‘Lax’ | 会话 cookie 的 SameSite |
SESSION_COOKIE_SECURE |
bool | False | 会话 cookie 是否仅 HTTPS |
SESSION_ENGINE |
str | ‘django.contrib.sessions.backends.db’ | 会话存储后端(5 种) |
SESSION_EXPIRE_AT_BROWSER_CLOSE |
bool | False | 关浏览器即过期 |
SESSION_FILE_PATH |
NoneType | None | file 后端的存放目录 |
SESSION_SAVE_EVERY_REQUEST |
bool | False | 每次请求都重发会话 cookie |
SESSION_SERIALIZER |
str | 'django.contrib.sessions.serializers.… | 会话序列化器 |
SHORT_DATETIME_FORMAT |
str | ‘m/d/Y P’ | 短日期时间格式 |
SHORT_DATE_FORMAT |
str | ‘m/d/Y’ | 短日期格式 |
SIGNED_COOKIE_LEGACY_SALT_FALLBACK |
bool | True | 是否兼容旧的签名 salt |
SIGNING_BACKEND |
str | ‘django.core.signing.TimestampSigner’ | 签名实现类 |
SILENCED_SYSTEM_CHECKS |
list | [](空列表) | 按 ID 静默系统检查 |
STATICFILES_DIRS |
list | [](空列表) | 项目级静态文件目录 |
STATICFILES_FINDERS |
list | 2 项,首项 'django.contrib.staticfiles.finder… | 静态文件查找器(整体替换) |
STATIC_ROOT |
NoneType | None | collectstatic 的输出目录 |
STATIC_URL |
NoneType | None | 静态文件的 URL 前缀 |
STORAGES |
dict | 2 键:default, staticfiles | 默认存储与静态存储(4.2 起) |
TEMPLATES |
list | [](空列表) | 模板引擎配置列表 |
TEST_NON_SERIALIZED_APPS |
list | [](空列表) | 并行测试时不序列化的 app |
TEST_RUNNER |
str | ‘django.test.runner.DiscoverRunner’ | 跑测试的入口类 |
THOUSAND_SEPARATOR |
str | ‘,’ | 千分位字符 |
TIME_FORMAT |
str | ‘P’ | 时间格式 |
TIME_INPUT_FORMATS |
list | 3 项,首项 ‘%H:%M:%S’ | 表单解析时间的候选格式 |
TIME_ZONE |
str | ‘America/Chicago’ | 项目时区(显示用) |
USE_I18N |
bool | True | 是否启用翻译 |
USE_THOUSAND_SEPARATOR |
bool | False | 是否分组显示数字 |
USE_TZ |
bool | True | 存 UTC、按 TIME_ZONE 显示 |
USE_X_FORWARDED_HOST |
bool | False | 是否认 X-Forwarded-Host |
USE_X_FORWARDED_PORT |
bool | False | 是否认 X-Forwarded-Port |
WSGI_APPLICATION |
NoneType | None | WSGI 入口的点路径 |
X_FRAME_OPTIONS |
str | ‘DENY’ | X-Frame-Options 的值 |
YEAR_MONTH_FORMAT |
str | ‘F Y’ | 年月格式 |
新手卡点清单
-
都是实测踩过的:
卡点 症状(实测原文) 正确做法 键名拼错或这版没这键 不报错、不生效; diffsettings里该行带###用 diffsettings/global_settings对一遍,别猜列表类设置只写自己那项 STATICFILES_DIRS突然失效(实测FileSystemFinder消失)从 global_settings拷全再追加改 USE_I18N用override_settings页面仍是中文(实测),新进程才变英文 翻译类改动另起进程验证 INSTALLED_APPS顺序随意django-admin-interface放admin之后主题完全不生效(实测 7232 vs 20546 字节)要覆盖 admin 模板的包排在 django.contrib.admin之前没配 SECRET_KEYImproperlyConfigured: The SECRET_KEY setting must not be empty.生成项目就带上,生产走环境变量 DEBUG=False没配ALLOWED_HOSTSDisallowedHost: Invalid HTTP_HOST header...+ 响应 400上线前把域名(含 .example.com通配)写全SameSite=None没配Secure浏览器丢弃 cookie,登录态刷新就掉 SESSION_COOKIE_SAMESITE="None"必须配SESSION_COOKIE_SECURE=True前端 JS 取不到 CSRF token 设了 CSRF_COOKIE_HTTPONLY=True后 fetch 报 403要么别开 HttpOnly,要么改用 session 存 token / 隐藏域 跨域前端提交表单 403 Origin: http://evil.example -> 403(实测可信源才 200)把前端源写进 CSRF_TRUSTED_ORIGINS(要带 scheme)表单字段特别多报 400 Too many GET/POST parameters(实测阈值 2 时三字段就 400)调 DATA_UPLOAD_MAX_NUMBER_FIELDS,不是 Django 坏了数字分隔符改了不生效 use_l10n=True下语言包赢(实测#被忽略)要 settings 说话就用 use_l10n=False或FORMAT_MODULE_PATH模型没写主键类型 models.W042警告(实测原文见上)配 DEFAULT_AUTO_FIELD或 AppConfig 的default_auto_fielddiffsettings --all崩UnicodeEncodeError: 'gbk' codec can't encode character '\xe5'加 PYTHONIOENCODING=utf-8(中文 Windows 特有)一个进程里反复 configure()RuntimeError: Settings already configured.每套配置起一个子进程 以为 settings.configured()是方法TypeError: 'bool' object is not callable它是 property,不带括号 生产开着 DEBUG500 页把 settings、SQL、请求头全摊开 DEBUG=False+ 正确的ALLOWED_HOSTS明文密码写进 settings 提交进仓库就泄露 password一律走环境变量,代码里只留键名
参考
- Django 官方文档:Settings:146 个键的权威说明与分组。
- Django 官方文档:Settings 与 global_settings:加载顺序、
configure()、DJANGO_SETTINGS_MODULE。 - Django 官方文档:Using Django’s settings:懒加载与自定义键的官方口径。
- Django 官方文档:diffsettings:
--all/--output unified的用法。 - Django 官方文档:How to deploy with WSGI:
WSGI_APPLICATION与部署侧的衔接。 - Django 源码
django/conf/__init__.py:LazySettings._setup与UserSettingsHolder。 - Django 源码
django/conf/global_settings.py:本篇 146 条默认值的出处。