相关配置
文件结构建议如下:
LinNote/
├── manage.py
├── LinNote/
│ ├── __init__.py
│ ├── asgi.py
│ ├── urls.py
│ ├── wsgi.py
│ └── settings/ ← 新建 settings 目录
│ ├── __init__.py ← 自动加载 dev 或 prod
│ ├── base.py ← 通用配置
│ ├── dev.py ← 开发环境配置
│ └── prod.py ← 生产环境配置
├── .venv
├── static/
├── templates/
├── blog/
├── linauth/
base.py
base.py
: 放通用配置,所有环境共用
"""
Django settings for LinNote project.
Generated by 'django-admin startproject' using Django 5.1.3.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
# BASE_DIR = Path(__file__).resolve().parent.parent
# __file__ :是当前文件的路径,resolve() 方法返回一个绝对路径,parent.parent.parent 是向上三层目录
# 这里的三层目录是为了确保 BASE_DIR 指向项目的根目录,而不是 settings.py 所在的目录
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
# SECRET_KEY = "django-insecure-o-tkk1*-9uygums#q9mhk^=g&@kj!+0m+q0#2e_e27k6!3yq#-"
# SECURITY WARNING: don't run with debug turned on in production!
# dev.py/prod.py 会覆盖
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"blog", # 添加你的应用
"linauth", # 添加你的应用
]
MIDDLEWARE = [
"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",
]
ROOT_URLCONF = "LinNote.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "LinNote.wsgi.application"
# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"] # 确保有这一行
# 这是浏览器访问用户上传文件(如图片、PDF 等)的 URL 前缀。
# 开发阶段:Django 的 runserver 可以处理 /media/ 请求,但需要手动配置 URL(见下文)。
# 生产环境:通常由 Web 服务器(Nginx/Apache)直接托管,Django 不处理。
MEDIA_URL = "/media/"
# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# @login_required 的 重定向 的URL
LOGIN_URL = "/auth/login"
dev.py
dev.py
:仅开发用配置,DEBUG=True
# settings/dev.py
from .base import *
DEBUG = True
ALLOWED_HOSTS = ["*"]
# prod.py 会重写
SECRET_KEY = "django-insecure-o-tkk1*-9uygums#q9mhk^=g&@kj!+0m+q0#2e_e27k6!3yq#-"
MEDIA_ROOT = BASE_DIR / "media" # 用户上传文件的存储目录
prod.py
prod.py
:仅生产用配置,DEBUG=False
# settings/prod.py
from .base import *
DEBUG = False
ALLOWED_HOSTS = [
"linnote.space",
"www.linnote.space",
"127.0.0.1",
"localhost",
"xx.xxx.xxx.xxx",
]
# 建议用环境变量读取 SECRET_KEY
import os
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "")
# 避免项目在缺少 SECRET_KEY 的情况下仍然启动:这样更安全、明确,避免漏配环境变量导致安全隐患
if not SECRET_KEY:
raise ValueError("DJANGO_SECRET_KEY environment variable not set!")
STATIC_ROOT = BASE_DIR / "staticfiles"
# 这是用户上传文件的存储目录(如 FileField 或 ImageField 上传的文件)。
# 你不需要手动创建它,Django 会在文件上传时自动创建。
MEDIA_ROOT = BASE_DIR / "mediafiles"
# 可选的安全增强配置:
# SECURE_BROWSER_XSS_FILTER 是一个安全设置,用于启用浏览器的 XSS 过滤器。
# XSS(跨站脚本攻击)是一种常见的安全漏洞,攻击者可以通过注入恶意脚本来窃取用户信息或执行其他恶意操作。
SECURE_BROWSER_XSS_FILTER = True
# SECURE_CONTENT_TYPE_NOSNIFF 是一个安全设置,用于防止浏览器猜测内容类型。
# 当启用时,浏览器将严格按照服务器提供的 Content-Type 头部来处理内容,而不是尝试猜测内容类型。
# 这有助于防止某些类型的攻击,例如 MIME 类型混淆攻击。
SECURE_CONTENT_TYPE_NOSNIFF = True
# SECURE_SSL_REDIRECT 是一个安全设置,用于强制将所有 HTTP 请求重定向到 HTTPS。
# 这有助于保护用户数据的安全性,防止中间人攻击。
# 如果你的网站使用 HTTPS,建议将其设置为 True。
SESSION_COOKIE_SECURE = True
# CSRF_COOKIE_SECURE 是一个安全设置,用于确保 CSRF(跨站请求伪造)令牌仅通过 HTTPS 传输。
# CSRF(Cross-Site Request Forgery)是一种攻击方式,攻击者诱使用户在不知情的情况下执行恶意操作。
CSRF_COOKIE_SECURE = True
# SECURE_HSTS_SECONDS 是一个安全设置,用于启用 HTTP 严格传输安全(HSTS)。
# HSTS 是一种安全机制,强制浏览器仅通过 HTTPS 访问网站。
# 当设置为非零值时,浏览器将记住该设置,并在指定的秒数内强制使用 HTTPS。
# 这里设置为 3600 秒(1 小时),可以根据需要调整。
SECURE_HSTS_SECONDS = 3600
__init__.py
__init__.py
:自动加载配置(默认 dev,可通过 DJANGO_ENV
切换)
# LinNote/settings/__init__.py
import os
env = os.getenv("DJANGO_ENV", "dev")
if env == "prod":
print("PROD environment detected, using production settings.")
from .prod import *
else:
print("DEV environment detected, using development settings.")
from .dev import *
配置环境变量
# 将环境变量写入到 bashrc里面
echo "export DJANGO_ENV=prod" >> ~/.bashrc
echo "export DJANGO_SECRET_KEY='your-very-secret-key'" >> ~/.bashrc
source ~/.bashrc
如何生成DJANGO_SECRET_KEY
在终端或 Python shell 中输入:
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())
# output: l&+fp(e2z=)^7on&n%o2ylcbjgho4*we9@v=mpjc1%9!6b41e9
SECRET_KEY
,可以这样设置:
export DJANGO_SECRET_KEY='l&+fp(e2z=)^7on&n%o2ylcbjgho4*we9@v=mpjc1%9!6b41e9'
相关说明
Django如何区分环境
在 manage.py
和 wsgi.py
中这行代码:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'LinNote.settings')
告诉 Django 去加载配置模块 LinNote.settings
,也就是说它会去找这个 Python 包(不是目录)下的内容。
如果 LinNote/settings
是一个文件夹 + 含 __init__.py
,它就是一个 Python 包,Django 就会执行这个包里的 __init__.py
文件,并把其中导入的变量(如 DEBUG
, DATABASES
, 等)作为配置加载。
所以 __init__.py
的作用是:它作为一个“中转站”,根据你设定的环境变量(如 DJANGO_ENV=prod
),动态地导入 dev.py
或 prod.py
的内容,从而控制加载哪个环境的配置。
# LinNote/settings/__init__.py
import os
### 根据环境变量 DJANGO_ENV 判断现在是开发环境还是生产环境
env = os.getenv("DJANGO_ENV", "dev")
if env == "prod":
print("PROD environment detected, using production settings.")
from .prod import *
else:
print("DEV environment detected, using development settings.")
from .dev import *
os.getenv("DJANGO_ENV", "dev")
方法会获取"DJANGO_ENV"
这个变量
在开发环境中不需要设置,因为如果
os.getenv
获取不到"DJANGO_ENV"
,就会返回默认值"dev"
在开发环境,就需要做如下配置:
echo "export DJANGO_ENV=prod" >> ~/.bashrc
这样,就可以区分开发环境了。
SECRET_KEY
SECRET_KEY
是 Django 中用于加密和签名的核心配置,它用于:
主要作用:
- 加密 session、cookies 和 CSRF token
- 签名密码重置链接
- 用于任何
cryptographic signing
的场景
安全警告:
- 不能暴露,因为攻击者可以伪造签名;
- 不能在不同环境复用,否则测试和生产环境可能互相干扰;
- 如果泄露,必须立刻更换并清除原先所有会话等签名数据。
开发环境: 可以使用默认 key。
SECRET_KEY = "django-insecure-o-tkk1*-9uygums#q9mhk^=g&@kj!+0m+q0#2e_e27k6!3yq#-"
生产环境: 应使用独立的、安全性高的 secret key,并确保不要泄露。可以从环境变量读取:
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "")
# 避免项目在缺少 SECRET_KEY 的情况下仍然启动:这样更安全、明确,避免漏配环境变量导致安全隐患
if not SECRET_KEY:
raise ValueError("DJANGO_SECRET_KEY environment variable not set!")
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com