You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django的post_save中发送邮件且不阻塞表单提交?

解决Django post_save发送邮件阻塞用户操作的问题

我来帮你搞定这个异步发邮件的问题!你的代码现在有个关键问题:sync_to_async的用法不对,导致邮件还是同步执行,硬生生卡住了用户请求。咱们一步步调整,让发邮件彻底不阻塞:

问题出在哪?

你现在是直接执行了call_submssion_email(instance),再把执行结果传给sync_to_async——这相当于还是同步跑完了发邮件的逻辑,完全没用到异步的优势。另外你函数名还拼错了(call_submssion_email少了个字母),先一起修正。

修改后的完整代码

from asgiref.sync import sync_to_async
import asyncio
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.mail import EmailMessage
from .models import SubmissionDetails  # 确保导入你的模型

@receiver(post_save, sender=SubmissionDetails)
def create_submission_email(sender, instance, created, **kwargs):
    if created:
        # 把同步函数包装成异步任务,丢到事件循环里后台执行
        asyncio.create_task(
            sync_to_async(call_manuscript_submission_email)(instance)
        )

def call_manuscript_submission_email(instance):
    print("Hi")
    message = '''Submitted with the title, <br> {0}'''.format(instance.title)
    subject = 'Article Submitted'
    to_address = 'example@gmail.com'
    from_address = "from@mail.example.com"
    msg = EmailMessage(
        subject, message, from_address, [to_address]
    )
    msg.content_subtype = "html"
    msg.send()

核心调整说明

  • 正确使用sync_to_async:要把同步函数本身(而不是函数执行结果)传给sync_to_async,再传入参数调用,这样才会把同步逻辑放到异步线程里执行。
  • 用asyncio.create_task启动任务:这个方法会把异步任务加入事件循环,主线程(处理用户请求的线程)会直接继续往下走,不用等邮件发送完成。
  • 注意运行环境:确保你的Django项目用ASGI服务器运行(比如Daphne),因为WSGI是同步环境,这种异步任务方式不会生效。你用的是带异步支持的Django 3.0,ASGI环境是前提。

额外提醒

如果需要邮件发送的可靠性(比如失败自动重试),这个轻量异步方案可能不够,这时候可以考虑用Celery、Django Q这类任务队列工具。但如果只是想解决“用户不用等邮件发完”的问题,上面的代码完全够用。

内容的提问来源于stack exchange,提问作者Amiya Behera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:27:58