如何在Django的Anymail中使用Postmark批量发送邮件?
Django + Anymail + Postmark 批量单收件人邮件优化方案
你遇到的循环逐个发送超时问题,核心是同步请求阻塞了页面响应,同时没利用Postmark的批量API能力。下面给你两种可行的解决思路:
一、用Anymail批量API一次性发送多封独立邮件
Postmark支持单次API请求发送最多500封独立邮件(每个收件人单独收到,无抄送/密送),Anymail封装了这个能力,比循环逐个发送效率高得多。
基于你现有代码改造的示例:
from anymail.message import AnymailMessage from django.core.mail import get_connection # 准备你的收件人列表、邮件内容等参数 recipient_list = ["user1@example.com", "user2@example.com", ...] subject = "统一主题" plain_text_body = "纯文本内容" html_body = "<p>HTML格式的邮件内容</p>" sender_email = "your-sender@domain.com" message_stream = "your-postmark-stream" # 批量构建邮件实例,每个实例对应一个收件人 messages = [] for to_addr in recipient_list: msg = AnymailMessage( subject=subject, body=plain_text_body, from_email=sender_email, to=[to_addr], # 每个邮件只填一个收件人 ) msg.attach_alternative(html_body, "text/html") msg.esp_extra = {'MessageStream': message_stream} messages.append(msg) # 一次性发送所有邮件 with get_connection() as conn: conn.send_messages(messages)
注意:Postmark单次批量请求最多支持500封邮件,如果你的收件人超过这个数,记得把列表拆分成多个500以内的批次分别发送。
二、异步发送彻底解决页面超时
如果收件人数量极大,哪怕用批量API,同步执行还是会占用请求时间导致超时。这时候把发送任务放到后台异步执行是最优解,推荐用Celery(Django生态最常用的异步任务队列)。
1. 编写异步发送任务
在你的app下创建tasks.py:
from celery import shared_task from anymail.message import AnymailMessage from django.core.mail import get_connection @shared_task def batch_send_emails(recipients, subject, plain_body, html_body, sender, stream): messages = [] for to_addr in recipients: msg = AnymailMessage( subject=subject, body=plain_body, from_email=sender, to=[to_addr], ) msg.attach_alternative(html_body, "text/html") msg.esp_extra = {'MessageStream': stream} messages.append(msg) with get_connection() as conn: conn.send_messages(messages)
2. 在视图中触发异步任务
把原来的同步发送代码改成调用异步任务,这样页面会立即返回,任务在后台执行:
from django.http import HttpResponse from .tasks import batch_send_emails def trigger_email_send(request): # 这里可以从请求或数据库获取收件人列表等参数 recipient_list = ["user1@example.com", "user2@example.com"] subject = "异步批量邮件测试" plain_body = "纯文本内容" html_body = "<h2>异步发送的HTML邮件</h2>" sender = "your-sender@domain.com" stream = "your-postmark-stream" # 调用异步任务,用delay()方法提交到Celery队列 batch_send_emails.delay(recipient_list, subject, plain_body, html_body, sender, stream) return HttpResponse("邮件发送任务已提交,后台处理中")
3. 启动Celery Worker
最后要启动Celery worker来处理后台任务:
celery -A your_django_project_name worker --loglevel=info
关键配置检查
确保你的settings.py中Anymail和Postmark的配置正确:
ANYMAIL = { "POSTMARK_SERVER_TOKEN": "你的Postmark服务器密钥", } EMAIL_BACKEND = "anymail.backends.postmark.EmailBackend"
内容的提问来源于stack exchange,提问作者coderDcoder
相关产品推荐
相关产品推荐

