refactor(email): 重构邮件配置从settings.py迁移到数据库

将邮件配置从Django的settings.py迁移到数据库的SystemConfig模型
更新测试文件以使用新的配置方式
添加邮件后端连接配置以提高灵活性
This commit is contained in:
2026-01-18 17:10:12 +08:00
parent 0049f23909
commit 9215de5a3d
5 changed files with 261 additions and 91 deletions

View File

@@ -24,6 +24,7 @@ def test_celery_email_config():
from django.conf import settings
from diary_family.celery import app
from core.models import SystemConfig
# 检查Celery配置
celery_config = {
@@ -45,12 +46,13 @@ def test_celery_email_config():
else:
logger.info(f" {key}: {value}")
# 检查邮件配置
# 从数据库获取邮件配置
config = SystemConfig.get_config()
email_config = {
'EMAIL_BACKEND': getattr(settings, 'EMAIL_BACKEND', None),
'EMAIL_HOST': getattr(settings, 'EMAIL_HOST', None),
'EMAIL_PORT': getattr(settings, 'EMAIL_PORT', None),
'EMAIL_HOST_USER': getattr(settings, 'EMAIL_HOST_USER', None),
'smtp_server': config.smtp_server,
'smtp_port': config.smtp_port,
'smtp_username': config.smtp_username,
'recipient_email': config.recipient_email,
}
logger.info("邮件配置信息:")
@@ -58,19 +60,18 @@ def test_celery_email_config():
if value is None:
logger.warning(f" {key}: 未配置")
else:
if 'password' in key.lower():
logger.info(f" {key}: ***")
else:
logger.info(f" {key}: {value}")
logger.info(f" {key}: {value}")
# 验证必要配置
missing_configs = []
if not getattr(settings, 'CELERY_BROKER_URL', None):
missing_configs.append('CELERY_BROKER_URL')
if not getattr(settings, 'EMAIL_HOST', None):
missing_configs.append('EMAIL_HOST')
if not getattr(settings, 'EMAIL_HOST_USER', None):
missing_configs.append('EMAIL_HOST_USER')
if not config.smtp_server:
missing_configs.append('smtp_server')
if not config.smtp_username:
missing_configs.append('smtp_username')
if not config.smtp_password:
missing_configs.append('smtp_password')
if missing_configs:
logger.error(f"缺少必要的配置: {', '.join(missing_configs)}")
@@ -179,16 +180,33 @@ def celery_send_test_email(self, test_mode=True):
logger.info(f"[任务 {task_id}] 开始执行异步邮件发送任务")
try:
# 获取邮件配置
from_email = getattr(settings, 'EMAIL_HOST_USER', None)
# 从数据库获取邮件配置
from core.models import SystemConfig
from django.core.mail.backends.smtp import EmailBackend
config = SystemConfig.get_config()
from_email = config.smtp_username
if not from_email:
raise ValueError("未配置发件邮箱 (EMAIL_HOST_USER)")
raise ValueError("未配置发件邮箱 (smtp_username)")
to_email = getattr(settings, 'EMAIL_HOST_USER', from_email)
if isinstance(to_email, list):
recipient_list = to_email
else:
recipient_list = [to_email]
to_email = config.recipient_email or from_email
recipient_list = [to_email]
# 获取SMTP配置
host = config.smtp_server or 'localhost'
port = config.smtp_port or 587
username = config.smtp_username or ''
password = config.smtp_password or ''
use_tls = True # 默认使用TLS
# 创建邮件后端
backend = EmailBackend(
host=host,
port=port,
username=username,
password=password,
use_tls=use_tls,
fail_silently=False
)
# 创建邮件内容
subject = f"[Celery测试] 异步邮件发送成功 - {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}"
@@ -206,8 +224,8 @@ def celery_send_test_email(self, test_mode=True):
- 执行重试次数: {self.request.retries}
邮件配置:
- 发件服务器: {getattr(settings, 'EMAIL_HOST', '未知')}:{getattr(settings, 'EMAIL_PORT', '未知')}
- 使用TLS: {getattr(settings, 'EMAIL_USE_TLS', '未知')}
- 发件服务器: {host}:{port}
- 使用TLS: {use_tls}
---
家庭日报系统
@@ -222,7 +240,7 @@ def celery_send_test_email(self, test_mode=True):
任务ID: {task_id}
这是一封测试邮件用于验证Celery异步邮件发送功能。
"
""
# 创建邮件
email = EmailMessage(
@@ -230,6 +248,7 @@ def celery_send_test_email(self, test_mode=True):
body=body,
from_email=from_email,
to=recipient_list,
connection=backend
)
email.content_subtype = 'plain'
email.encoding = 'utf-8'
@@ -294,17 +313,27 @@ def celery_send_html_report_email(self, include_attachment=False):
logger.info(f"[任务 {task_id}] 开始执行HTML报告邮件发送任务")
try:
# 获取邮件配置
from_email = getattr(settings, 'EMAIL_HOST_USER', None)
# 从数据库获取邮件配置
from core.models import SystemConfig
from django.core.mail.backends.smtp import EmailBackend
config = SystemConfig.get_config()
from_email = config.smtp_username
if not from_email:
raise ValueError("未配置发件邮箱")
to_email = getattr(settings, 'EMAIL_HOST_USER', from_email)
to_email = config.recipient_email or from_email
if isinstance(to_email, list):
recipient_list = to_email
else:
recipient_list = [to_email]
# 获取SMTP配置
host = config.smtp_server or 'localhost'
port = config.smtp_port or 587
username = config.smtp_username or ''
password = config.smtp_password or ''
use_tls = True # 默认使用TLS
# 准备报告数据
today = timezone.now().date()
yesterday = today - timedelta(days=1)
@@ -374,6 +403,16 @@ def celery_send_html_report_email(self, include_attachment=False):
</html>
"""
# 创建邮件后端
backend = EmailBackend(
host=host,
port=port,
username=username,
password=password,
use_tls=use_tls,
fail_silently=False
)
# 创建邮件
subject = f"[Celery] 家庭日报 {report_data['today']} - 测试报告"
@@ -382,6 +421,7 @@ def celery_send_html_report_email(self, include_attachment=False):
body=html_content,
from_email=from_email,
to=recipient_list,
connection=backend
)
email.attach_alternative(html_content, "text/html")
email.encoding = 'utf-8'
@@ -525,9 +565,34 @@ def main():
from django.conf import settings
from django.core.mail import EmailMessage
from django.utils import timezone
from core.models import SystemConfig
from django.core.mail.backends.smtp import EmailBackend
from_email = getattr(settings, 'EMAIL_HOST_USER', None)
to_email = getattr(settings, 'EMAIL_HOST_USER', from_email)
# 从数据库获取邮件配置
config = SystemConfig.get_config()
from_email = config.smtp_username
if not from_email:
raise ValueError("未配置发件邮箱")
to_email = config.recipient_email or from_email
recipient_list = [to_email] if isinstance(to_email, str) else to_email
# 获取SMTP配置
host = config.smtp_server or 'localhost'
port = config.smtp_port or 587
username = config.smtp_username or ''
password = config.smtp_password or ''
use_tls = True # 默认使用TLS
# 创建邮件后端
backend = EmailBackend(
host=host,
port=port,
username=username,
password=password,
use_tls=use_tls,
fail_silently=False
)
subject = f"[直接测试] Celery邮件测试 - {timezone.now().strftime('%H:%M:%S')}"
body = f"""
@@ -547,7 +612,8 @@ def main():
subject=subject,
body=body,
from_email=from_email,
to=[to_email] if isinstance(to_email, str) else to_email,
to=recipient_list,
connection=backend
)
sent = email.send(fail_silently=False)