求助:Django项目中筛选数据库记录并按指定格式发送至邮箱
Django新手指南:筛选数据库记录并发送格式化邮件
1. 筛选数据库记录
假设你有一个Order模型(根据实际业务调整),用Django的QuerySet就能轻松筛选符合条件的记录。比如筛选最近7天内状态为"未处理"的订单:
from django.utils import timezone import datetime from .models import Order # 计算7天前的时间点 seven_days_ago = timezone.now() - datetime.timedelta(days=7) # 按条件筛选记录 filtered_records = Order.objects.filter( status='unprocessed', created_at__gte=seven_days_ago ) # 检查是否有符合条件的记录 if not filtered_records.exists(): print("没有符合条件的记录,无需发送邮件")
QuerySet的筛选参数可按需调整,比如created_at__lte(小于等于指定时间)、customer__name__contains(客户名称包含指定字符)等,灵活组合即可满足不同需求。
2. 格式化记录内容
把筛选后的记录转换成邮件支持的格式(纯文本或HTML),以下是两种常用格式示例:
纯文本格式
def format_to_text(records): text = f"【系统通知】最近7天未处理订单列表\n\n" for idx, order in enumerate(records, 1): text += ( f"{idx}. 订单号: {order.id}\n" f" 客户名称: {order.customer_name}\n" f" 创建时间: {order.created_at.strftime('%Y-%m-%d %H:%M')}\n" f" 订单金额: {order.amount}元\n\n" ) return text
HTML格式(适合美观的邮件展示)
def format_to_html(records): html = """ <html> <head> <style> table {border-collapse: collapse; width: 100%;} th, td {border: 1px solid #ddd; padding: 8px; text-align: left;} th {background-color: #f2f2f2;} </style> </head> <body> <h2>【系统通知】最近7天未处理订单列表</h2> <table> <tr> <th>序号</th> <th>订单号</th> <th>客户名称</th> <th>创建时间</th> <th>订单金额</th> </tr> """ for idx, order in enumerate(records, 1): html += f""" <tr> <td>{idx}</td> <td>{order.id}</td> <td>{order.customer_name}</td> <td>{order.created_at.strftime('%Y-%m-%d %H:%M')}</td> <td>{order.amount}元</td> </tr> """ html += """ </table> </body> </html> """ return html
3. 配置Django邮件功能
在项目的settings.py中添加SMTP配置(以QQ邮箱为例,其他邮箱替换对应参数即可):
# settings.py EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' # SMTP服务器地址 EMAIL_PORT = 587 # SMTP端口 EMAIL_USE_TLS = True # 启用TLS加密 EMAIL_HOST_USER = 'your_qq_email@qq.com' # 你的邮箱地址 EMAIL_HOST_PASSWORD = 'your_smtp_auth_code' # 邮箱SMTP授权码(不是登录密码) DEFAULT_FROM_EMAIL = EMAIL_HOST_USER # 默认发件人
注意:不同邮箱的SMTP规则不同,比如Gmail需要开启"应用专用密码",QQ邮箱需在设置中开启POP3/SMTP服务并获取授权码。
4. 发送邮件
用Django的EmailMultiAlternatives类可同时发送纯文本和HTML格式邮件,适配不同邮箱客户端:
from django.core.mail import EmailMultiAlternatives from django.utils import timezone from .models import Order from .utils import format_to_text, format_to_html # 假设格式化函数放在utils.py中 def send_records_email(): # 1. 筛选记录 seven_days_ago = timezone.now() - datetime.timedelta(days=7) filtered_orders = Order.objects.filter( status='unprocessed', created_at__gte=seven_days_ago ) if not filtered_orders.exists(): return # 2. 格式化内容 text_content = format_to_text(filtered_orders) html_content = format_to_html(filtered_orders) # 3. 构建并发送邮件 subject = f"未处理订单通知 - {timezone.now().strftime('%Y-%m-%d')}" to_emails = ['recipient@example.com'] # 指定收件邮箱 msg = EmailMultiAlternatives(subject, text_content, None, to_emails) msg.attach_alternative(html_content, "text/html") msg.send()
5. 触发邮件发送
你可以通过以下方式触发发送逻辑:
- 手动触发:在Django shell中执行
from yourapp.utils import send_records_email; send_records_email() - 管理命令:创建自定义命令,方便命令行执行(适合定时任务)
- 定时任务:用
django-crontab或Celery实现定时发送(比如每天早9点自动发送)
自定义管理命令示例
在你的app下创建management/commands/send_order_notice.py文件:
from django.core.management.base import BaseCommand from yourapp.utils import send_records_email class Command(BaseCommand): help = '发送未处理订单通知邮件' def handle(self, *args, **options): send_records_email() self.stdout.write(self.style.SUCCESS('邮件发送完成!'))
命令行执行:
python manage.py send_order_notice
内容的提问来源于stack exchange,提问作者Furkan Yıldız
相关产品推荐
相关产品推荐

