|
|
|
|
@ -9,335 +9,367 @@ https://docs.djangoproject.com/en/1.10/topics/settings/
|
|
|
|
|
For the full list of settings and their values, see
|
|
|
|
|
https://docs.djangoproject.com/en/1.10/ref/settings/
|
|
|
|
|
"""
|
|
|
|
|
# 导入系统模块
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
from pathlib import Path # 用于处理文件路径的现代化方式
|
|
|
|
|
|
|
|
|
|
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'
|
|
|
|
|
"""
|
|
|
|
|
将环境变量转换为布尔值
|
|
|
|
|
|
|
|
|
|
参数:
|
|
|
|
|
env: 环境变量名称
|
|
|
|
|
default: 默认值
|
|
|
|
|
|
|
|
|
|
返回:
|
|
|
|
|
布尔值
|
|
|
|
|
"""
|
|
|
|
|
str_val = os.environ.get(env) # 获取环境变量值
|
|
|
|
|
return default if str_val is None else str_val == 'True' # 如果未设置则使用默认值,否则判断是否为 'True'
|
|
|
|
|
|
|
|
|
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
|
|
|
|
# 构建项目内的路径,使用 Path 对象更安全和跨平台
|
|
|
|
|
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 = 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 = env_to_bool('DJANGO_DEBUG', True)
|
|
|
|
|
# DEBUG = False
|
|
|
|
|
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
|
|
|
|
|
# 安全警告:在生产环境中不要开启调试模式
|
|
|
|
|
DEBUG = env_to_bool('DJANGO_DEBUG', True) # 从环境变量获取调试设置,默认为 True
|
|
|
|
|
# DEBUG = False # 注释掉的代码:手动设置调试模式为 False
|
|
|
|
|
|
|
|
|
|
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test' # 判断是否在运行测试
|
|
|
|
|
|
|
|
|
|
# ALLOWED_HOSTS = []
|
|
|
|
|
ALLOWED_HOSTS = ['*', '127.0.0.1', 'example.com']
|
|
|
|
|
# django 4.0新增配置
|
|
|
|
|
# ALLOWED_HOSTS = [] # 注释掉的默认配置
|
|
|
|
|
ALLOWED_HOSTS = ['*', '127.0.0.1', 'example.com'] # 允许的主机列表,* 表示允许所有主机
|
|
|
|
|
|
|
|
|
|
# django 4.0新增配置 - CSRF 可信来源
|
|
|
|
|
CSRF_TRUSTED_ORIGINS = ['http://example.com']
|
|
|
|
|
# Application definition
|
|
|
|
|
|
|
|
|
|
# Application definition
|
|
|
|
|
# 应用定义:列出项目中使用的所有 Django 应用
|
|
|
|
|
|
|
|
|
|
INSTALLED_APPS = [
|
|
|
|
|
# 'django.contrib.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.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', # Markdown 编辑器
|
|
|
|
|
'haystack', # 全文搜索框架
|
|
|
|
|
'blog', # 博客应用
|
|
|
|
|
'accounts', # 账户管理应用
|
|
|
|
|
'comments', # 评论应用
|
|
|
|
|
'oauth', # OAuth 认证应用
|
|
|
|
|
'servermanager', # 服务器管理应用
|
|
|
|
|
'owntracks', # 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', # 安全中间件
|
|
|
|
|
'django.contrib.sessions.middleware.SessionMiddleware', # 会话中间件
|
|
|
|
|
'django.middleware.locale.LocaleMiddleware', # 国际化中间件
|
|
|
|
|
'django.middleware.gzip.GZipMiddleware', # GZip 压缩中间件
|
|
|
|
|
# 'django.middleware.cache.UpdateCacheMiddleware', # 注释掉的缓存更新中间件
|
|
|
|
|
'django.middleware.common.CommonMiddleware', # 通用中间件
|
|
|
|
|
# 'django.middleware.cache.FetchFromCacheMiddleware', # 注释掉的缓存获取中间件
|
|
|
|
|
'django.middleware.csrf.CsrfViewMiddleware', # CSRF 保护中间件
|
|
|
|
|
'django.contrib.auth.middleware.AuthenticationMiddleware', # 认证中间件
|
|
|
|
|
'django.contrib.messages.middleware.MessageMiddleware', # 消息中间件
|
|
|
|
|
'django.middleware.clickjacking.XFrameOptionsMiddleware', # 点击劫持保护中间件
|
|
|
|
|
'django.middleware.http.ConditionalGetMiddleware', # 条件 GET 中间件
|
|
|
|
|
'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', # 使用 Django 模板引擎
|
|
|
|
|
'DIRS': [os.path.join(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',
|
|
|
|
|
'blog.context_processors.seo_processor'
|
|
|
|
|
'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' # 自定义 SEO 上下文处理器
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
WSGI_APPLICATION = 'djangoblog.wsgi.application'
|
|
|
|
|
WSGI_APPLICATION = 'djangoblog.wsgi.application' # WSGI 应用入口
|
|
|
|
|
|
|
|
|
|
# Database
|
|
|
|
|
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
|
|
|
|
|
|
|
|
|
|
# 数据库配置:使用 MySQL
|
|
|
|
|
|
|
|
|
|
DATABASES = {
|
|
|
|
|
'default': {
|
|
|
|
|
'ENGINE': 'django.db.backends.mysql',
|
|
|
|
|
'NAME': os.environ.get('DJANGO_MYSQL_DATABASE') or 'djangoblog',
|
|
|
|
|
'USER': os.environ.get('DJANGO_MYSQL_USER') or 'root',
|
|
|
|
|
'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or '123456',
|
|
|
|
|
'HOST': os.environ.get('DJANGO_MYSQL_HOST') or '127.0.0.1',
|
|
|
|
|
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
|
|
|
|
|
'NAME': os.environ.get('DJANGO_MYSQL_DATABASE') or 'djangoblog', # 数据库名称
|
|
|
|
|
'USER': os.environ.get('DJANGO_MYSQL_USER') or 'root', # 数据库用户名
|
|
|
|
|
'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or '123456', # 数据库密码
|
|
|
|
|
'HOST': os.environ.get('DJANGO_MYSQL_HOST') or '127.0.0.1', # 数据库主机
|
|
|
|
|
'PORT': int(
|
|
|
|
|
os.environ.get('DJANGO_MYSQL_PORT') or 3306),
|
|
|
|
|
os.environ.get('DJANGO_MYSQL_PORT') or 3306), # 数据库端口
|
|
|
|
|
'OPTIONS': {
|
|
|
|
|
'charset': 'utf8mb4'},
|
|
|
|
|
'charset': 'utf8mb4'}, # 字符集配置
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
# Password validation
|
|
|
|
|
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
|
|
|
|
|
# 密码验证器配置
|
|
|
|
|
|
|
|
|
|
AUTH_PASSWORD_VALIDATORS = [
|
|
|
|
|
{
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', # 用户属性相似性验证
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', # 最小长度验证
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', # 常见密码验证
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
|
|
|
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', # 数字密码验证
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
LANGUAGES = (
|
|
|
|
|
('en', _('English')),
|
|
|
|
|
('zh-hans', _('Simplified Chinese')),
|
|
|
|
|
('zh-hant', _('Traditional Chinese')),
|
|
|
|
|
# 国际化配置
|
|
|
|
|
LANGUAGES = ( # 支持的语言列表
|
|
|
|
|
('en', _('English')), # 英语
|
|
|
|
|
('zh-hans', _('Simplified Chinese')), # 简体中文
|
|
|
|
|
('zh-hant', _('Traditional Chinese')), # 繁体中文
|
|
|
|
|
)
|
|
|
|
|
LOCALE_PATHS = (
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
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/
|
|
|
|
|
# 静态文件配置
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HAYSTACK_CONNECTIONS = {
|
|
|
|
|
HAYSTACK_CONNECTIONS = { # Haystack 搜索引擎配置
|
|
|
|
|
'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
|
|
|
|
|
AUTHENTICATION_BACKENDS = [
|
|
|
|
|
'accounts.user_login_backend.EmailOrUsernameModelBackend']
|
|
|
|
|
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' # 实时更新搜索索引
|
|
|
|
|
|
|
|
|
|
STATIC_ROOT = os.path.join(BASE_DIR, 'collectedstatic')
|
|
|
|
|
# Allow user login with username and password
|
|
|
|
|
AUTHENTICATION_BACKENDS = [ # 认证后端配置
|
|
|
|
|
'accounts.user_login_backend.EmailOrUsernameModelBackend' # 允许使用邮箱或用户名登录
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
STATIC_URL = '/static/'
|
|
|
|
|
STATICFILES = os.path.join(BASE_DIR, 'static')
|
|
|
|
|
STATIC_ROOT = os.path.join(BASE_DIR, 'collectedstatic') # 静态文件收集目录
|
|
|
|
|
STATIC_URL = '/static/' # 静态文件 URL 前缀
|
|
|
|
|
STATICFILES = os.path.join(BASE_DIR, 'static') # 静态文件目录
|
|
|
|
|
|
|
|
|
|
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'
|
|
|
|
|
TIME_FORMAT = '%Y-%m-%d %H:%M:%S' # 时间格式
|
|
|
|
|
DATE_TIME_FORMAT = '%Y-%m-%d' # 日期格式
|
|
|
|
|
|
|
|
|
|
# bootstrap color styles
|
|
|
|
|
BOOTSTRAP_COLOR_TYPES = [
|
|
|
|
|
BOOTSTRAP_COLOR_TYPES = [ # Bootstrap 颜色样式列表
|
|
|
|
|
'default', 'primary', 'success', 'info', 'warning', 'danger'
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
# paginate
|
|
|
|
|
PAGINATE_BY = 10
|
|
|
|
|
PAGINATE_BY = 10 # 分页每页显示数量
|
|
|
|
|
# http cache timeout
|
|
|
|
|
CACHE_CONTROL_MAX_AGE = 2592000
|
|
|
|
|
CACHE_CONTROL_MAX_AGE = 2592000 # HTTP 缓存最大年龄(30天)
|
|
|
|
|
|
|
|
|
|
# cache setting
|
|
|
|
|
CACHES = {
|
|
|
|
|
CACHES = { # 缓存配置
|
|
|
|
|
'default': {
|
|
|
|
|
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
|
|
|
|
'TIMEOUT': 10800,
|
|
|
|
|
'LOCATION': 'unique-snowflake',
|
|
|
|
|
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 使用本地内存缓存
|
|
|
|
|
'TIMEOUT': 10800, # 缓存超时时间(3小时)
|
|
|
|
|
'LOCATION': 'unique-snowflake', # 缓存位置标识
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
# 使用redis作为缓存
|
|
|
|
|
|
|
|
|
|
# 使用 redis 作为缓存(如果配置了环境变量)
|
|
|
|
|
if os.environ.get("DJANGO_REDIS_URL"):
|
|
|
|
|
CACHES = {
|
|
|
|
|
'default': {
|
|
|
|
|
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
|
|
|
|
|
'LOCATION': f'redis://{os.environ.get("DJANGO_REDIS_URL")}',
|
|
|
|
|
'BACKEND': 'django.core.cache.backends.redis.RedisCache', # 使用 Redis 缓存
|
|
|
|
|
'LOCATION': f'redis://{os.environ.get("DJANGO_REDIS_URL")}', # Redis 连接地址
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
# Email 配置:
|
|
|
|
|
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 # 服务器错误邮件发送地址
|
|
|
|
|
|
|
|
|
|
# Setting debug=false did NOT handle except email notifications
|
|
|
|
|
ADMINS = [('admin', os.environ.get('DJANGO_ADMIN_EMAIL') or 'admin@admin.com')]
|
|
|
|
|
ADMINS = [('admin', os.environ.get('DJANGO_ADMIN_EMAIL') or 'admin@admin.com')] # 管理员邮箱
|
|
|
|
|
|
|
|
|
|
# WX ADMIN password(Two times md5)
|
|
|
|
|
WXADMIN = os.environ.get(
|
|
|
|
|
'DJANGO_WXADMIN_PASSWORD') or '995F03AC401D6CABABAEF756FC4D43C7'
|
|
|
|
|
'DJANGO_WXADMIN_PASSWORD') or '995F03AC401D6CABABAEF756FC4D43C7' # 微信管理员密码(两次 MD5 加密)
|
|
|
|
|
|
|
|
|
|
LOG_PATH = os.path.join(BASE_DIR, 'logs')
|
|
|
|
|
# 日志配置
|
|
|
|
|
LOG_PATH = os.path.join(BASE_DIR, 'logs') # 日志文件路径
|
|
|
|
|
if not os.path.exists(LOG_PATH):
|
|
|
|
|
os.makedirs(LOG_PATH, exist_ok=True)
|
|
|
|
|
os.makedirs(LOG_PATH, exist_ok=True) # 创建日志目录
|
|
|
|
|
|
|
|
|
|
LOGGING = {
|
|
|
|
|
'version': 1,
|
|
|
|
|
'disable_existing_loggers': False,
|
|
|
|
|
'root': {
|
|
|
|
|
'level': 'INFO',
|
|
|
|
|
'handlers': ['console', 'log_file'],
|
|
|
|
|
'version': 1, # 日志配置版本
|
|
|
|
|
'disable_existing_loggers': False, # 不禁用现有的日志记录器
|
|
|
|
|
'root': { # 根日志记录器
|
|
|
|
|
'level': 'INFO', # 日志级别
|
|
|
|
|
'handlers': ['console', 'log_file'], # 处理器
|
|
|
|
|
},
|
|
|
|
|
'formatters': {
|
|
|
|
|
'formatters': { # 日志格式化器
|
|
|
|
|
'verbose': {
|
|
|
|
|
'format': '[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d %(module)s] %(message)s',
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'filters': {
|
|
|
|
|
'filters': { # 日志过滤器
|
|
|
|
|
'require_debug_false': {
|
|
|
|
|
'()': 'django.utils.log.RequireDebugFalse',
|
|
|
|
|
'()': 'django.utils.log.RequireDebugFalse', # 要求调试为 False
|
|
|
|
|
},
|
|
|
|
|
'require_debug_true': {
|
|
|
|
|
'()': 'django.utils.log.RequireDebugTrue',
|
|
|
|
|
'()': 'django.utils.log.RequireDebugTrue', # 要求调试为 True
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
'handlers': {
|
|
|
|
|
'handlers': { # 日志处理器
|
|
|
|
|
'log_file': {
|
|
|
|
|
'level': 'INFO',
|
|
|
|
|
'class': 'logging.handlers.TimedRotatingFileHandler',
|
|
|
|
|
'filename': os.path.join(LOG_PATH, 'djangoblog.log'),
|
|
|
|
|
'when': 'D',
|
|
|
|
|
'formatter': 'verbose',
|
|
|
|
|
'interval': 1,
|
|
|
|
|
'delay': True,
|
|
|
|
|
'backupCount': 5,
|
|
|
|
|
'encoding': 'utf-8'
|
|
|
|
|
'level': 'INFO', # 处理器级别
|
|
|
|
|
'class': 'logging.handlers.TimedRotatingFileHandler', # 按时间轮转的文件处理器
|
|
|
|
|
'filename': os.path.join(LOG_PATH, 'djangoblog.log'), # 日志文件名
|
|
|
|
|
'when': 'D', # 每天轮转
|
|
|
|
|
'formatter': 'verbose', # 使用详细格式
|
|
|
|
|
'interval': 1, # 轮转间隔
|
|
|
|
|
'delay': True, # 延迟创建文件
|
|
|
|
|
'backupCount': 5, # 保留备份数量
|
|
|
|
|
'encoding': 'utf-8' # 文件编码
|
|
|
|
|
},
|
|
|
|
|
'console': {
|
|
|
|
|
'level': 'DEBUG',
|
|
|
|
|
'filters': ['require_debug_true'],
|
|
|
|
|
'class': 'logging.StreamHandler',
|
|
|
|
|
'formatter': 'verbose'
|
|
|
|
|
'level': 'DEBUG', # 控制台处理器级别
|
|
|
|
|
'filters': ['require_debug_true'], # 仅在调试模式下使用
|
|
|
|
|
'class': 'logging.StreamHandler', # 控制台处理器
|
|
|
|
|
'formatter': 'verbose' # 使用详细格式
|
|
|
|
|
},
|
|
|
|
|
'null': {
|
|
|
|
|
'class': 'logging.NullHandler',
|
|
|
|
|
'class': 'logging.NullHandler', # 空处理器
|
|
|
|
|
},
|
|
|
|
|
'mail_admins': {
|
|
|
|
|
'level': 'ERROR',
|
|
|
|
|
'filters': ['require_debug_false'],
|
|
|
|
|
'class': 'django.utils.log.AdminEmailHandler'
|
|
|
|
|
'level': 'ERROR', # 邮件处理器级别
|
|
|
|
|
'filters': ['require_debug_false'], # 仅在非调试模式下使用
|
|
|
|
|
'class': 'django.utils.log.AdminEmailHandler' # 管理员邮件处理器
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'loggers': {
|
|
|
|
|
'loggers': { # 日志记录器配置
|
|
|
|
|
'djangoblog': {
|
|
|
|
|
'handlers': ['log_file', 'console'],
|
|
|
|
|
'level': 'INFO',
|
|
|
|
|
'propagate': True,
|
|
|
|
|
'handlers': ['log_file', 'console'], # 使用的处理器
|
|
|
|
|
'level': 'INFO', # 日志级别
|
|
|
|
|
'propagate': True, # 是否传播到父级记录器
|
|
|
|
|
},
|
|
|
|
|
'django.request': {
|
|
|
|
|
'handlers': ['mail_admins'],
|
|
|
|
|
'level': 'ERROR',
|
|
|
|
|
'propagate': False,
|
|
|
|
|
'handlers': ['mail_admins'], # 错误请求发送邮件给管理员
|
|
|
|
|
'level': 'ERROR', # 错误级别
|
|
|
|
|
'propagate': False, # 不传播到父级记录器
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 静态文件查找器配置
|
|
|
|
|
STATICFILES_FINDERS = (
|
|
|
|
|
'django.contrib.staticfiles.finders.FileSystemFinder',
|
|
|
|
|
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
|
|
|
|
'django.contrib.staticfiles.finders.FileSystemFinder', # 文件系统查找器
|
|
|
|
|
'django.contrib.staticfiles.finders.AppDirectoriesFinder', # 应用目录查找器
|
|
|
|
|
# other
|
|
|
|
|
'compressor.finders.CompressorFinder',
|
|
|
|
|
'compressor.finders.CompressorFinder', # 压缩文件查找器
|
|
|
|
|
)
|
|
|
|
|
COMPRESS_ENABLED = True
|
|
|
|
|
# COMPRESS_OFFLINE = True
|
|
|
|
|
|
|
|
|
|
COMPRESS_ENABLED = True # 启用静态文件压缩
|
|
|
|
|
# COMPRESS_OFFLINE = True # 注释掉的离线压缩配置
|
|
|
|
|
|
|
|
|
|
# CSS 压缩过滤器
|
|
|
|
|
COMPRESS_CSS_FILTERS = [
|
|
|
|
|
# creates absolute urls from relative ones
|
|
|
|
|
'compressor.filters.css_default.CssAbsoluteFilter',
|
|
|
|
|
'compressor.filters.css_default.CssAbsoluteFilter', # 创建绝对 URL
|
|
|
|
|
# css minimizer
|
|
|
|
|
'compressor.filters.cssmin.CSSMinFilter'
|
|
|
|
|
'compressor.filters.cssmin.CSSMinFilter' # CSS 最小化
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
# JavaScript 压缩过滤器
|
|
|
|
|
COMPRESS_JS_FILTERS = [
|
|
|
|
|
'compressor.filters.jsmin.JSMinFilter'
|
|
|
|
|
'compressor.filters.jsmin.JSMinFilter' # JS 最小化
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
|
|
|
|
|
MEDIA_URL = '/media/'
|
|
|
|
|
X_FRAME_OPTIONS = 'SAMEORIGIN'
|
|
|
|
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads') # 媒体文件上传目录
|
|
|
|
|
MEDIA_URL = '/media/' # 媒体文件 URL 前缀
|
|
|
|
|
X_FRAME_OPTIONS = 'SAMEORIGIN' # X-Frame-Options 安全头设置
|
|
|
|
|
|
|
|
|
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
|
|
|
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # 默认自动字段类型
|
|
|
|
|
|
|
|
|
|
# 如果配置了 Elasticsearch,则使用 Elasticsearch 作为搜索后端
|
|
|
|
|
if os.environ.get('DJANGO_ELASTICSEARCH_HOST'):
|
|
|
|
|
ELASTICSEARCH_DSL = {
|
|
|
|
|
'default': {
|
|
|
|
|
'hosts': os.environ.get('DJANGO_ELASTICSEARCH_HOST')
|
|
|
|
|
'hosts': os.environ.get('DJANGO_ELASTICSEARCH_HOST') # Elasticsearch 主机地址
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
HAYSTACK_CONNECTIONS = {
|
|
|
|
|
'default': {
|
|
|
|
|
'ENGINE': 'djangoblog.elasticsearch_backend.ElasticSearchEngine',
|
|
|
|
|
'ENGINE': 'djangoblog.elasticsearch_backend.ElasticSearchEngine', # 使用自定义 Elasticsearch 后端
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Plugin System
|
|
|
|
|
PLUGINS_DIR = BASE_DIR / 'plugins'
|
|
|
|
|
ACTIVE_PLUGINS = [
|
|
|
|
|
'article_copyright',
|
|
|
|
|
'reading_time',
|
|
|
|
|
'external_links',
|
|
|
|
|
'view_count',
|
|
|
|
|
'seo_optimizer'
|
|
|
|
|
]
|
|
|
|
|
# 插件系统配置
|
|
|
|
|
PLUGINS_DIR = BASE_DIR / 'plugins' # 插件目录路径
|
|
|
|
|
ACTIVE_PLUGINS = [ # 激活的插件列表
|
|
|
|
|
'article_copyright', # 文章版权插件
|
|
|
|
|
'reading_time', # 阅读时间插件
|
|
|
|
|
'external_links', # 外部链接插件
|
|
|
|
|
'view_count', # 浏览量统计插件
|
|
|
|
|
'seo_optimizer' # SEO 优化插件
|
|
|
|
|
]
|
|
|
|
|
|