【问题标题】:Asynchronious email sending in DjangoDjango中的异步电子邮件发送
【发布时间】:2016-08-05 17:11:47
【问题描述】:

我正在尝试弄清楚如何异步发送电子邮件,这样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

【问题讨论】:

  • 您是否在本地开发设置中使用CELERY_ALWAYS_EAGER = True
  • 是的,我尝试将其放入 settings.py 中...但不幸的是,它没有帮助。

标签: python django django-celery django-email


【解决方案1】:

问题

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

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

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


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

A.启动 SMTP 服务器并使用您自己的客户端

选项 1

运行组合的 SMTP 服务器和客户端。 Mailcatcher 非常适合这个。

它甚至带有django setup instructions

设置然后启动它:

$ mailcatcher -fv

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

对于 docker 用户,您可以获得mailcatcher docker image


选项 2

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

例如使用简单的 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 或类似的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-25
    • 2012-08-11
    • 2011-03-25
    • 1970-01-01
    • 2011-05-06
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多