添加 settings.py 注释

jyf_branch
姜雨菲 4 months ago
parent f7675c6ff7
commit da0d5ef30a

@ -17,109 +17,99 @@ from django.utils.translation import gettext_lazy as _
def env_to_bool(env, default):
"""将环境变量值转换为布尔值的工具函数"""
str_val = os.environ.get(env)
return default if str_val is None else str_val == 'True'
# Build paths inside the project like this: BASE_DIR / 'subdir'.
#姜雨菲: 构建项目路径BASE_DIR为项目根目录
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
#姜雨菲: 快速开发设置 - 不适用于生产环境
# 安全警告生产环境中请保持SECRET_KEY的机密性
SECRET_KEY = os.environ.get(
'DJANGO_SECRET_KEY') or 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6'
# SECURITY WARNING: don't run with debug turned on in production!
# 安全警告生产环境中请关闭DEBUG模式
DEBUG = env_to_bool('DJANGO_DEBUG', True)
# DEBUG = False
# 测试环境标识当执行测试命令时为True
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
# ALLOWED_HOSTS = []
# 允许访问的主机,生产环境需配置具体域名
ALLOWED_HOSTS = ['*', '127.0.0.1', 'example.com']
# django 4.0新增配置
# Django 4.0新增配置指定可信任的CSRF来源
CSRF_TRUSTED_ORIGINS = ['http://example.com']
# Application definition
# 应用定义
INSTALLED_APPS = [
# 'django.contrib.admin',
# 自定义的Admin配置简化版
'django.contrib.admin.apps.SimpleAdminConfig',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django.contrib.sitemaps',
'mdeditor',
'haystack',
'blog',
'accounts',
'comments',
'oauth',
'servermanager',
'owntracks',
'compressor',
'djangoblog'
'django.contrib.auth', # 用户认证应用
'django.contrib.contenttypes', # 内容类型框架
'django.contrib.sessions', # 会话框架
'django.contrib.messages', # 消息框架
'django.contrib.staticfiles', # 静态文件管理
'django.contrib.sites', # 站点框架(用于多站点管理)
'django.contrib.sitemaps', # 站点地图框架
'mdeditor', # Markdown编辑器应用
'haystack', # 搜索框架
'blog', # 博客应用
'accounts', # 用户账户应用
'comments', # 评论应用
'oauth', # 第三方登录应用
'servermanager', # 服务器管理应用
'owntracks', # 位置追踪应用
'compressor', # 静态文件压缩应用
'djangoblog' # 项目主应用
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.gzip.GZipMiddleware',
# 'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.cache.FetchFromCacheMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.http.ConditionalGetMiddleware',
'blog.middleware.OnlineMiddleware'
'django.middleware.security.SecurityMiddleware', # 安全中间件处理HTTPS等安全相关
'django.contrib.sessions.middleware.SessionMiddleware', # 会话中间件
'django.middleware.locale.LocaleMiddleware', # 国际化中间件(语言切换)
'django.middleware.gzip.GZipMiddleware', # GZip压缩中间件
'django.middleware.common.CommonMiddleware', # 通用中间件(处理请求/响应)
'django.middleware.csrf.CsrfViewMiddleware', # CSRF保护中间件
'django.contrib.auth.middleware.AuthenticationMiddleware', # 认证中间件
'django.contrib.messages.middleware.MessageMiddleware', # 消息中间件
'django.middleware.clickjacking.XFrameOptionsMiddleware', # 点击劫持保护中间件
'django.middleware.http.ConditionalGetMiddleware', # 条件获取中间件处理304响应
'blog.middleware.OnlineMiddleware' # 自定义在线用户统计中间件
]
ROOT_URLCONF = 'djangoblog.urls'
ROOT_URLCONF = 'djangoblog.urls' # 项目URL配置入口
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'BACKEND': 'django.template.backends.django.DjangoTemplates', # 模板引擎
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 自定义模板目录
'APP_DIRS': True, # 是否自动搜索应用内的templates目录
'OPTIONS': {
'context_processors': [
'context_processors': [ # 模板上下文处理器
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'blog.context_processors.seo_processor'
'blog.context_processors.seo_processor' # 自定义SEO上下文处理器
],
},
},
]
WSGI_APPLICATION = 'djangoblog.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
WSGI_APPLICATION = 'djangoblog.wsgi.application' # WSGI应用入口
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djangoblog',
'USER': 'root',
'PASSWORD': '050807',
'HOST': '127.0.0.1',
'PORT': 3306,
'ENGINE': 'django.db.backends.mysql', # 使用MySQL数据库引擎
'NAME': 'djangoblog', # 数据库名
'USER': 'root', # 数据库用户名
'PASSWORD': '050807', # 数据库密码
'HOST': '127.0.0.1', # 数据库主机
'PORT': 3306, # 数据库端口
}
}
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
# 密码验证配置
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@ -135,75 +125,72 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
# 支持的语言列表(国际化配置)
LANGUAGES = (
('en', _('English')),
('zh-hans', _('Simplified Chinese')),
('zh-hant', _('Traditional Chinese')),
)
# 语言文件路径
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
LANGUAGE_CODE = 'zh-hans' # 默认语言
TIME_ZONE = 'Asia/Shanghai' # 时区
USE_I18N = True # 启用国际化
USE_L10N = True # 启用本地化格式
USE_TZ = False # 不使用时区感知模型
# 搜索框架Haystack配置
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'djangoblog.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
'ENGINE': 'djangoblog.whoosh_cn_backend.WhooshEngine', # 使用Whoosh搜索引擎中文适配版
'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'), # 索引存储路径
},
}
# Automatically update searching index
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# Allow user login with username and password
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' # 实时信号处理器(自动更新索引)
# 认证后端配置(支持用户名或邮箱登录)
AUTHENTICATION_BACKENDS = [
'accounts.user_login_backend.EmailOrUsernameModelBackend']
STATIC_ROOT = os.path.join(BASE_DIR, 'collectedstatic')
# 静态文件配置
STATIC_ROOT = os.path.join(BASE_DIR, 'collectedstatic') # 静态文件收集目录(生产环境用)
STATIC_URL = '/static/' # 静态文件URL前缀
STATICFILES = os.path.join(BASE_DIR, 'static') # 静态文件源目录
STATIC_URL = '/static/'
STATICFILES = os.path.join(BASE_DIR, 'static')
# 添加插件静态文件目录
# 插件静态文件目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'plugins'), # 让Django能找到插件静态文件
os.path.join(BASE_DIR, 'plugins'), # 插件静态文件目录
]
AUTH_USER_MODEL = 'accounts.BlogUser'
LOGIN_URL = '/login/'
AUTH_USER_MODEL = 'accounts.BlogUser' # 自定义用户模型
LOGIN_URL = '/login/' # 登录URL
# 时间格式定义
TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
DATE_TIME_FORMAT = '%Y-%m-%d'
# bootstrap color styles
# Bootstrap颜色样式
BOOTSTRAP_COLOR_TYPES = [
'default', 'primary', 'success', 'info', 'warning', 'danger'
]
# paginate
# 分页配置
PAGINATE_BY = 10
# http cache timeout
# HTTP缓存超时时间
CACHE_CONTROL_MAX_AGE = 2592000
# cache setting
# 缓存配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 10800,
'LOCATION': 'unique-snowflake',
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 本地内存缓存
'TIMEOUT': 10800, # 缓存超时时间(秒)
'LOCATION': 'unique-snowflake', # 缓存位置标识
}
}
# 使用redis作为缓存
# 若存在环境变量则使用Redis作为缓存
if os.environ.get("DJANGO_REDIS_URL"):
CACHES = {
'default': {
@ -212,26 +199,28 @@ if os.environ.get("DJANGO_REDIS_URL"):
}
}
SITE_ID = 1
SITE_ID = 1 # 站点ID多站点时使用
# 百度链接提交通知URL
BAIDU_NOTIFY_URL = os.environ.get('DJANGO_BAIDU_NOTIFY_URL') \
or 'http://data.zz.baidu.com/urls?site=https://www.lylinux.net&token=1uAOGrMsUm5syDGn'
# Email:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = env_to_bool('DJANGO_EMAIL_TLS', False)
EMAIL_USE_SSL = env_to_bool('DJANGO_EMAIL_SSL', True)
EMAIL_HOST = os.environ.get('DJANGO_EMAIL_HOST') or 'smtp.mxhichina.com'
EMAIL_PORT = int(os.environ.get('DJANGO_EMAIL_PORT') or 465)
EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_USER')
EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_PASSWORD')
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER
# Setting debug=false did NOT handle except email notifications
# 邮件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # SMTP邮件后端
EMAIL_USE_TLS = env_to_bool('DJANGO_EMAIL_TLS', False) # 是否使用TLS
EMAIL_USE_SSL = env_to_bool('DJANGO_EMAIL_SSL', True) # 是否使用SSL
EMAIL_HOST = os.environ.get('DJANGO_EMAIL_HOST') or 'smtp.mxhichina.com' # 邮件服务器
EMAIL_PORT = int(os.environ.get('DJANGO_EMAIL_PORT') or 465) # 邮件端口
EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_USER') # 邮件用户名
EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_PASSWORD') # 邮件密码
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER # 默认发件人
SERVER_EMAIL = EMAIL_HOST_USER # 服务器邮件发件人
# 管理员邮件通知配置
ADMINS = [('admin', os.environ.get('DJANGO_ADMIN_EMAIL') or 'admin@admin.com')]
# WX ADMIN password(Two times md5)
# 微信管理密码两次MD5加密
WXADMIN = os.environ.get(
'DJANGO_WXADMIN_PASSWORD') or '995F03AC401D6CABABAEF756FC4D43C7'
# 日志配置
LOG_PATH = os.path.join(BASE_DIR, 'logs')
if not os.path.exists(LOG_PATH):
os.makedirs(LOG_PATH, exist_ok=True)
@ -297,74 +286,67 @@ LOGGING = {
}
}
# 静态文件查找器用于Compressor
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# other
'compressor.finders.CompressorFinder',
)
COMPRESS_ENABLED = True
COMPRESS_ENABLED = True # 启用静态文件压缩
# 根据环境变量决定是否启用离线压缩
COMPRESS_OFFLINE = os.environ.get('COMPRESS_OFFLINE', 'False').lower() == 'true'
# 压缩输出目录
COMPRESS_OUTPUT_DIR = 'compressed'
COMPRESS_OUTPUT_DIR = 'compressed' # 压缩文件输出目录
COMPRESS_CSS_HASHING_METHOD = 'mtime' # CSS哈希生成方式基于修改时间
COMPRESS_JS_HASHING_METHOD = 'mtime' # JS哈希生成方式基于修改时间
# 压缩文件名模板 - 包含哈希值用于缓存破坏
COMPRESS_CSS_HASHING_METHOD = 'mtime'
COMPRESS_JS_HASHING_METHOD = 'mtime'
# 高级CSS压缩过滤器
# CSS压缩过滤器
COMPRESS_CSS_FILTERS = [
# 创建绝对URL
'compressor.filters.css_default.CssAbsoluteFilter',
# CSS压缩器 - 高压缩等级
'compressor.filters.cssmin.CSSCompressorFilter',
'compressor.filters.css_default.CssAbsoluteFilter', # 处理CSS中的绝对URL
'compressor.filters.cssmin.CSSCompressorFilter', # CSS压缩器
]
# 高级JS压缩过滤器
# JS压缩过滤器
COMPRESS_JS_FILTERS = [
# JS压缩器 - 高压缩等级
'compressor.filters.jsmin.SlimItFilter',
'compressor.filters.jsmin.SlimItFilter', # JS压缩器
]
# 压缩缓存配置
COMPRESS_CACHE_BACKEND = 'default'
COMPRESS_CACHE_KEY_FUNCTION = 'compressor.cache.simple_cachekey'
COMPRESS_CACHE_BACKEND = 'default' # 压缩缓存后端
COMPRESS_CACHE_KEY_FUNCTION = 'compressor.cache.simple_cachekey' # 缓存键生成函数
# 预压缩配置
# 预编译器配置支持SCSS/SASS
COMPRESS_PRECOMPILERS = (
# 支持SCSS/SASS
('text/x-scss', 'django_libsass.SassCompiler'),
('text/x-sass', 'django_libsass.SassCompiler'),
)
# 压缩性能优化
COMPRESS_MINT_DELAY = 30 # 压缩延迟(秒)
COMPRESS_MTIME_DELAY = 10 # 修改时间检查延迟
COMPRESS_REBUILD_TIMEOUT = 2592000 # 重建超时30天
# 压缩性能优化配置
COMPRESS_MINT_DELAY = 30
COMPRESS_MTIME_DELAY = 10
COMPRESS_REBUILD_TIMEOUT = 2592000
# 压缩等级配置
COMPRESS_CSS_COMPRESSOR = 'compressor.css.CssCompressor'
COMPRESS_JS_COMPRESSOR = 'compressor.js.JsCompressor'
# 静态文件缓存配置
# 静态文件存储带Manifest用于缓存破坏
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
# 浏览器缓存配置(通过中间件或服务器配置)
COMPRESS_URL = STATIC_URL
COMPRESS_ROOT = STATIC_ROOT
# 媒体文件(用户上传文件)配置
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = '/media/'
# XFrameOptions配置允许同域iframe
X_FRAME_OPTIONS = 'SAMEORIGIN'
# 安全头部配置 - 防XSS和其他攻击
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin'
# 安全头部配置
SECURE_BROWSER_XSS_FILTER = True # 启用XSS过滤
SECURE_CONTENT_TYPE_NOSNIFF = True # 禁止内容类型嗅探
SECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin' # Referrer策略
# 内容安全策略 (CSP) - 防XSS攻击
# 内容安全策略CSP
CSP_DEFAULT_SRC = ["'self'"]
CSP_SCRIPT_SRC = ["'self'", "'unsafe-inline'", "cdn.mathjax.org", "*.googleapis.com"]
CSP_STYLE_SRC = ["'self'", "'unsafe-inline'", "*.googleapis.com", "*.gstatic.com"]
@ -374,8 +356,9 @@ CSP_CONNECT_SRC = ["'self'"]
CSP_FRAME_SRC = ["'none'"]
CSP_OBJECT_SRC = ["'none'"]
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # 默认自增字段类型
# 若存在环境变量则使用Elasticsearch作为搜索后端
if os.environ.get('DJANGO_ELASTICSEARCH_HOST'):
ELASTICSEARCH_DSL = {
'default': {
@ -388,15 +371,14 @@ if os.environ.get('DJANGO_ELASTICSEARCH_HOST'):
},
}
# Plugin System
# 插件系统配置
PLUGINS_DIR = BASE_DIR / 'plugins'
ACTIVE_PLUGINS = [
'article_copyright',
'reading_time',
'external_links',
'view_count',
'seo_optimizer',
'image_lazy_loading',
'article_recommendation',
]
'article_copyright', # 文章版权插件
'reading_time', # 阅读时间插件
'external_links', # 外部链接插件
'view_count', # 阅读计数插件
'seo_optimizer', # SEO优化插件
'image_lazy_loading', # 图片懒加载插件
'article_recommendation', # 文章推荐插件
]
Loading…
Cancel
Save