Django - 如何在发送邮件时重定向

Posted

技术标签:

【中文标题】Django - 如何在发送邮件时重定向【英文标题】:Django - how to redirect while sending mail 【发布时间】:2020-06-11 13:19:21 【问题描述】:

问题:是否可以在发送电子邮件时重定向页面。发送邮件需要 5 到 10 秒。在这段时间内,页面没有做任何事情。用户可能会重新提交表单以提示做出反应。所以我在想也许有一种方法可以在保存对象后立即重定向页面,而不是在发送邮件后重定向。代码如下:

@login_required
def handle_order(request, **kwargs):
    ....
    order = form.save(commit=False)
    order.active = True
    order.save()

    # send email to the user, 5-10 seconds waiting time
    kwargs = ...
    mail_order_detail(**kwargs)

    return redirect('shopping:show-order', order.ref_number)

我尝试使用post_save 信号,不工作,仍然需要等待才能被重定向

【问题讨论】:

为什么不使用django的send_mail功能?文档:docs.djangoproject.com/en/3.0/topics/email/… 我实际上是在使用send_mass_mail函数,mail_order_detail函数包括那个 好的,太好了!!!。 【参考方案1】:

如果您的设置发送邮件需要很长时间,最好使用某种 cronjob 或后台队列来发送邮件。

例如为您的邮件创建一个新模型,只需在数据库中插入您要发送的邮件,然后创建一个每分钟运行一次的 cron 作业,发送模型中收集的所有邮件。

【讨论】:

谢谢!好吧,是这个还是 Celery 异步任务管理器?我对 Django 还很陌生,Celery 是不是必须要尝尝这个? 如果你只是想发送邮件,我认为 celery 有点过分......这也取决于你的托管解决方案......你可以简单地添加 cron 任务吗?如果您使用 uwsgi 作为服务器,它也可以这样做:pypi.org/project/uwsgi-tasks【参考方案2】:

通常,您不会在请求期间发送电子邮件,而是使用某种邮件队列:在您的数据库中创建电子邮件或将其发送到某种外部作业队列,并拥有一个其他进程或系统实际上分别进行邮件发送(并重试,因为失败很常见)。

【讨论】:

感谢 Masklinn 的回答,我现在正在研究“cron 工作”!干杯【参考方案3】:

看来您需要异步操作! (至少,这是我的假设,哈哈)

现在,我要建议的内容可能会给您的项目带来过多的开销(如果您仅将其用于一项操作)

您可以利用库 - Celery - 创建异步任务。使用 Celery,您可以使用 apply_async() 方法,这样您视图中的其余代码可以在发送邮件时继续执行。

https://hackernoon.com/asynchronous-tasks-with-celery-redis-in-django-3e00d3735686

编辑:Masklinn 的解决方案可能更节省时间和成本!

【讨论】:

【参考方案4】:

使用诸如 Celery 之类的异步任务管理器来升级您的应用程序似乎是一个很好的理由。有一个很好的教程seting up celery and the async email sender task on a django app。一旦你安装了 celery 并运行了它的一个实例——查看教程——你可以编写一个类似的函数,如下所示:

from celery import shared_task 

from django.core.mail import send_mail

@shared_task
def send_email_task():
    send_mail('Celery Task Worked!',
    'This is proof the task worked!',
    'support@prettyprinted.com',
    ['sasa@be-breathtaking.net'])

    return None

在您的 django 路由上,您可以调用异步任务,这样您的用户就不必等待发送电子邮件来接收 http 响应:

from .tasks import send_email_task

def index(request):
    send_email_task.delay()
    return HttpResponse('<h1>EMAIL HAS BEEN SENT WITH CELERY!</h1>')

【讨论】:

感谢 Kenny 的直截了当的回答和教程链接。 erm .. 你会说 cron 工作更适合这项任务吗?我对 Django 很陌生,我有 2 个答案,所以...... 两种解决方案都可以很好地满足您的需求,celery 将是一个更好的选择,因为它更具可扩展性 - 即您可以使用相同的任务队列和多个服务器。有一个有趣的answer on this matter here。

以上是关于Django - 如何在发送邮件时重定向的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中接受垃圾 url 时重定向到登录页面

如何在 django 中通过电子邮件发送链接?

如何使用 Python/Django 在电子邮件中发送内联图像? [复制]

如何使用 Python/Django 在电子邮件中发送内联图像? [复制]

使用 django 发送邮件黑猩猩设计的电子邮件

如何使用 django-mailer 定时发送电子邮件