You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Django/doc/djangoblog/settings.py

345 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
Django settings for djangoblog project.
Generated by 'django-admin startproject' using Django 1.10.2.
For more information on this file, see
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 _
def env_to_bool(env, default):
"""将环境变量转换为布尔值"""
str_val = os.environ.get(env)
return default if str_val is None else str_val == 'True'
# 构建项目内部路径BASE_DIR / 'subdir'
BASE_DIR = Path(__file__).resolve().parent.parent
# 快速开发配置 - 不适用于生产环境
# 参见 https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# 安全警告:在生产环境中保持密钥保密!
SECRET_KEY = os.environ.get(
'DJANGO_SECRET_KEY') or 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6'
# 安全警告:在生产环境中不要开启调试模式!
DEBUG = env_to_bool('DJANGO_DEBUG', True)
# DEBUG = False
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test' # 检测是否在测试模式
# 允许的主机名
# ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*', '127.0.0.1', 'example.com']
# Django 4.0新增配置受信任的CSRF来源
CSRF_TRUSTED_ORIGINS = ['http://example.com']
# 应用定义
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', # Markdown编辑器
'haystack', # 搜索框架
'blog', # 博客应用
'accounts', # 账户应用
'comments', # 评论应用
'oauth', # OAuth认证
'servermanager', # 服务器管理
'owntracks', # 位置跟踪
'compressor', # 静态文件压缩
'djangoblog' # 主应用
]
# 中间件配置
MIDDLEWARE = [
'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' # 自定义在线用户中间件
]
# 根URL配置
ROOT_URLCONF = 'djangoblog.urls'
# 模板配置
TEMPLATES = [
{
'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' # 自定义SEO处理器
],
},
},
]
# WSGI应用配置
WSGI_APPLICATION = 'djangoblog.wsgi.application'
# 数据库配置
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # MySQL数据库引擎
'NAME': os.environ.get('DJANGO_MYSQL_DATABASE') or 'djangoblog', # 数据库名
'USER': os.environ.get('DJANGO_MYSQL_USER') or 'django_user', # 用户名
'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or 'wzm216921', # 密码
'HOST': os.environ.get('DJANGO_MYSQL_HOST') or '127.0.0.1', # 主机
'PORT': int(
os.environ.get('DJANGO_MYSQL_PORT') or 3306), # 端口
'OPTIONS': {
'charset': 'utf8mb4'}, # 字符集配置
}}
# 密码验证
# 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.MinimumLengthValidator', # 最小长度验证
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', # 常见密码验证
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', # 数字密码验证
},
]
# 国际化配置
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 # 不使用时区支持
# 静态文件 (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
# Haystack搜索配置
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'djangoblog.whoosh_cn_backend.WhooshEngine', # Whoosh搜索引擎
'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'), # 索引路径
},
}
# 自动更新搜索索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# 允许用户使用邮箱或用户名登录
AUTHENTICATION_BACKENDS = [
'accounts.user_login_backend.EmailOrUsernameModelBackend']
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/' # 登录URL
TIME_FORMAT = '%Y-%m-%d %H:%M:%S' # 时间格式
DATE_TIME_FORMAT = '%Y-%m-%d' # 日期格式
# bootstrap颜色样式
BOOTSTRAP_COLOR_TYPES = [
'default', 'primary', 'success', 'info', 'warning', 'danger'
]
# 分页设置
PAGINATE_BY = 10
# HTTP缓存超时时间
CACHE_CONTROL_MAX_AGE = 2592000
# 缓存设置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 本地内存缓存
'TIMEOUT': 10800, # 缓存超时时间3小时
'LOCATION': 'unique-snowflake', # 缓存位置标识
}
}
# 使用redis作为缓存
if os.environ.get("DJANGO_REDIS_URL"):
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache', # Redis缓存后端
'LOCATION': f'redis://{os.environ.get("DJANGO_REDIS_URL")}', # Redis连接URL
}
}
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_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' # SMTP主机
EMAIL_PORT = int(os.environ.get('DJANGO_EMAIL_PORT') or 465) # SMTP端口
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 # 服务器邮箱
# 设置debug=false不会处理异常邮件通知
ADMINS = [('admin', os.environ.get('DJANGO_ADMIN_EMAIL') or 'admin@admin.com')] # 管理员邮箱
# 微信管理员密码两次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) # 创建日志目录
LOGGING = {
'version': 1, # 日志配置版本
'disable_existing_loggers': False, # 不禁用现有日志记录器
'root': {
'level': 'INFO', # 根日志级别
'handlers': ['console', 'log_file'], # 处理器
},
'formatters': { # 日志格式
'verbose': {
'format': '[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d %(module)s] %(message)s', # 详细格式
}
},
'filters': { # 过滤器
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse', # 要求调试模式为False
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue', # 要求调试模式为True
},
},
'handlers': { # 处理器
'log_file': {
'level': 'INFO', # 日志级别
'class': 'logging.handlers.TimedRotatingFileHandler', # 按时间轮转的文件处理器
'filename': os.path.join(LOG_PATH, 'djangoblog.log'), # 日志文件路径
'when': 'D', # 按天轮转
'formatter': 'verbose', # 使用详细格式
'interval': 1, # 间隔1天
'delay': True, # 延迟创建
'backupCount': 5, # 保留5个备份
'encoding': 'utf-8' # 文件编码
},
'console': { # 控制台处理器
'level': 'DEBUG',
'filters': ['require_debug_true'], # 仅在调试模式下生效
'class': 'logging.StreamHandler',
'formatter': 'verbose'
},
'null': { # 空处理器
'class': 'logging.NullHandler',
},
'mail_admins': { # 管理员邮件处理器
'level': 'ERROR',
'filters': ['require_debug_false'], # 仅在非调试模式下生效
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': { # 日志记录器
'djangoblog': {
'handlers': ['log_file', 'console'],
'level': 'INFO',
'propagate': True, # 向上传播
},
'django.request': { # Django请求日志
'handlers': ['mail_admins'], # 发送邮件给管理员
'level': 'ERROR',
'propagate': False, # 不向上传播
}
}
}
# 静态文件查找器
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder', # 文件系统查找器
'django.contrib.staticfiles.finders.AppDirectoriesFinder', # 应用目录查找器
# other
'compressor.finders.CompressorFinder', # 压缩文件查找器
)
COMPRESS_ENABLED = True # 启用压缩
# COMPRESS_OFFLINE = True # 离线压缩(注释)
# CSS压缩过滤器
COMPRESS_CSS_FILTERS = [
# 从相对URL创建绝对URL
'compressor.filters.css_default.CssAbsoluteFilter',
# CSS压缩器
'compressor.filters.cssmin.CSSMinFilter'
]
# JS压缩过滤器
COMPRESS_JS_FILTERS = [
'compressor.filters.jsmin.JSMinFilter' # JS压缩器
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads') # 媒体文件根目录
MEDIA_URL = '/media/' # 媒体文件URL
X_FRAME_OPTIONS = 'SAMEORIGIN' # 帧选项:同源策略
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # 默认自增字段类型
# Elasticsearch配置
if os.environ.get('DJANGO_ELASTICSEARCH_HOST'):
ELASTICSEARCH_DSL = {
'default': {
'hosts': os.environ.get('DJANGO_ELASTICSEARCH_HOST') # Elasticsearch主机
},
}
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'djangoblog.elasticsearch_backend.ElasticSearchEngine', # Elasticsearch引擎
},
}
# 插件系统
PLUGINS_DIR = BASE_DIR / 'plugins' # 插件目录
ACTIVE_PLUGINS = [ # 激活的插件列表
'article_copyright', # 文章版权
'reading_time', # 阅读时间
'external_links', # 外部链接
'view_count', # 浏览量统计
'seo_optimizer' # SEO优化
]