在Django发送异步电子邮件

时间:2016-08-05 17:11:48

标签: python django django-celery django-email

我试图弄清楚如何异步发送电子邮件,因此User不必等到发送email

我已安装celerydjango-celery-email并将django-celery-email添加到我的settings.py - djcelery_email

我还改变了数据库后端:

EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend'

现在我已尝试执行一项动作,该动作会发送电子邮件但冻结并且未发送任何电子邮件。

你知道该怎么办吗?

这是cmd的追溯:

Internal Server Error: /ajax/reservation/confirm/
Traceback (most recent call last):
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\views.py", line 68, in reservation_confirm
    reservation.save()
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\models.py", line 150, in save
    notifications.AdminNotifications.new_pair(self, paired_reservation)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\notifications.py", line 79, in new_pair
    send_message_to_admin(subject,message)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\dolava_app\notifications.py", line 8, in send_message_to_admin
    mail.send()
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\django\core\mail\message.py", line 292, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\djcelery_email\backends.py", line 17, in send_messages
    result_tasks.append(send_emails.delay(chunk, self.init_kwargs))
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\task.py", line 453, in delay
    return self.apply_async(args, kwargs)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\task.py", line 565, in apply_async
    **dict(self._get_exec_options(), **options)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\base.py", line 354, in send_task
    reply_to=reply_to or self.oid, **options
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\celery\app\amqp.py", line 310, in publish_task
    **kwargs
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\messaging.py", line 172, in publish
    routing_key, mandatory, immediate, exchange, declare)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 457, in _ensured
    interval_max)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 369, in ensure_connection
    interval_start, interval_step, interval_max, callback)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\utils\__init__.py", line 246, in retry_over_time
    return fun(*args, **kwargs)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 237, in connect
    return self.connection
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 742, in connection
    self._connection = self._establish_connection()
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\connection.py", line 697, in _establish_connection
    conn = self.transport.establish_connection()
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\kombu\transport\pyamqp.py", line 116, in establish_connection
    conn = self.Connection(**opts)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\connection.py", line 165, in __init__
    self.transport = self.Transport(host, connect_timeout, ssl)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\connection.py", line 186, in Transport
    return create_transport(host, connect_timeout, ssl)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\transport.py", line 299, in create_transport
    return TCPTransport(host, connect_timeout)
  File "C:\Users\Milano\PycharmProjects\FutileStudio\dolava\venv\lib\site-packages\amqp\transport.py", line 95, in __init__
    raise socket.error(last_err)
error: [Errno 10061] No connection could be made because the target machine actively refused it

1 个答案:

答案 0 :(得分:1)

问题

来自https://github.com/pmclanahan/django-celery-email

  

默认情况下,django-celery-email将使用Django内置的SMTP电子邮件   实际发送邮件的后端。

这意味着您需要在本地运行SMTP服务器才能接受该电子邮件。这就是您收到套接字错误的原因 - 因为您没有设置任何SMTP服务器来接收电子邮件。


可能的解决方案 - 本地发展

一种。启动SMTP服务器并使用您自己的客户端

选项1

运行组合的SMTP服务器和客户端。 Mailcatcher对此非常有用。

它甚至带有django setup instructions

设置然后用以下方法启动它:

$ mailcatcher -fv

注意:mailcatcher需要安装gem(ruby包管理器)。 所以你必须先安装它。 它可能值得努力,因为mailcatcher工作得非常好 在浏览器选项卡中为您提供电子邮件的html和文本表示。

对于泊坞广告用户,您可以获得mailcatcher docker image


选项2

运行您自己的SMTP服务器和单独的邮件客户端。

e.g。使用简单的python SMTP服务器 从命令行 python -m smtpd -n -c DebuggingServer localhost:1025

在您的django设置中

EMAIL_HOST = 'localhost' EMAIL_HOST_USER = None EMAIL_HOST_PASSWORD = None EMAIL_PORT = 1025 EMAIL_USE_TLS = False

然后,您需要设置客户端以获取这些电子邮件。


B中。不要在您的设置中使用SMTP作为后端

而是打印到控制台:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

问题是难看的格式化。 HTML将显示为文本,使电子邮件很难阅读。您可以通过手动将其复制并粘贴到.html文件并在浏览器中打开来将其输出到文件中,但这样会非常快。


解决方案 - 持续集成服务器

使用此功能使django测试客户端可以访问电子邮件,这样您就可以检查是否已发送电子邮件,以编程方式检查电子邮件的内容等。 EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

解决方案 - 生产服务器

您需要再次使用SMTP服务器。 您可以自己运行或使用Sendgrid,Mailgun,Mandrill或类似的东西。