【问题标题】:EmailBackend for sending email through multiple SMTP in DjangoEmailBackend 用于在 Django 中通过多个 SMTP 发送电子邮件
【发布时间】:2012-11-15 10:40:50
【问题描述】:

使用标准设置很好地解释了让 Django 发送电子邮件here,如下所示。

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = "mail.mysmtpserver.somewhere"
#EMAIL_PORT
EMAIL_HOST_USER = "my@login"
EMAIL_HOST_PASSWORD = "mypassword"
#EMAIL_USE_TLS = True

然后使用django.core.mail.EmailMessage发送。

但是,如果您运行多个站点并且需要每个站点通过它们自己的 SMTP 服务器发送电子邮件(或者只是在同一个 SMTP 服务器中的不同登录名),该怎么办?

搜索这样的 EmailBackend 或使用当前后端执行此操作的方法没有产生任何令人满意的结果。

【问题讨论】:

    标签: django email smtp


    【解决方案1】:

    如果您想覆盖提供的设置,您可以创建自己的连接并将其提供给 send_emailEmailMessage

    from django.core.mail import get_connection, send_mail
    from django.core.mail.message import EmailMessage
    # TODO: Insert clever settings mechanism
    my_host = ''
    my_port = 587
    my_username = ''
    my_password = ''
    my_use_tls = True
    connection = get_connection(host=my_host, 
                                port=my_port, 
                                username=my_username, 
                                password=my_password, 
                                use_tls=my_use_tls) 
    
    send_mail('diditwork?', 'test message', 'from_email', ['to'], connection=connection)
    # or
    EmailMessage('diditwork?', 'test message', 'from_email', ['to'], connection=connection).send(fail_silently=False)
    

    更新:确保在使用后关闭连接,@michel.iamit 答案指向显示连接已缓存以供 smpt 的代码。 @dhackner 回答展示了如何使用 with 语句自动关闭连接。

    【讨论】:

    • 我在使用这个解决方案时发现的东西是 Celery/Kombu cant pickle the EmailMessage 当你传递一个连接对象时,所以我认为这个方法在为将来安排电子邮件时可能不起作用交货
    • 您可能永远不应该尝试腌制“连接”,因为它可能在未来的任务中不可用。如果只是将数据传递给未来的任务,并且在任务执行时构造 EmailMessage,它应该可以工作......
    【解决方案2】:

    我会稍微修改 Daniel Backman 的答案,以使用文档中的上下文管理器。它会自己处理 open() 和 close() 调用。

    from django.core.mail import get_connection, send_mail
    from django.core.mail.message import EmailMessage
    
    with get_connection(
        host=my_host, 
        port=my_port, 
        username=my_username, 
        password=my_password, 
        use_tls=my_use_tls
    ) as connection:
        EmailMessage(subject1, body1, from1, [to1],
                     connection=connection).send()
    

    https://docs.djangoproject.com/en/dev/topics/email/#email-backends

    【讨论】:

    • 确实是一个更优雅的解决方案,只是一个说明,它仅在当前的django开发版本(> 1.7)中可用
    • 如果您使用的是django
    • 我想我找到了。 connection.close()。我应该猜到了。 :)
    • 参数应该是use_tls 而不是@paketep 指出的user_tls
    【解决方案3】:

    对不起,不能直接评论其余的答案,没有足够的代表。

    只有一个补充:

    connection = get_connection(host=my_host, 
                                    port=my_port, 
                                    username=my_username, 
                                    password=my_password, 
                                    user_tls=my_use_tls)
    

    应该是

    connection = get_connection(host=my_host, 
                                    port=my_port, 
                                    username=my_username, 
                                    password=my_password, 
                                    use_tls=my_use_tls)
    

    只有在您不使用 TLS 时才会出现问题(您应该这样做),因为它默认为 True。

    【讨论】:

    • @Manish,是的! “user_tls”与“use_tls”
    • @RajkumarRajendran:好的。无论如何,您可能刚刚提到了那个特定的参数。 ;)
    • @ManishMunikar 这不是我的答案。我回复了你的评论;)
    【解决方案4】:

    看看 django 的电子邮件后端并创建一个自定义的可能是一个想法。

    这里是代码:https://github.com/django/django/blob/master/django/core/mail/backends/smtp.py

    这个例子展示了如何定制一个(这个使用 SMTP_SSL 而不是 SMTP):

    https://gist.github.com/jsummerfield/1486891

    我分叉了一个,将两者结合起来(这样我就可以将一个后端用于具有不同邮件设置的不同站点):

    https://gist.github.com/iamit/5415771

    不确定这是否可行,但如您所见,如果已经存在连接,则上述所有代码都会在打开连接时返回... 所以也许你的解决方案已经开始了......不要这样做,关闭打开的连接并使用不同的设置重新打开......(不确定这是否有效)。

    【讨论】:

      【解决方案5】:

      为每个站点使用不同的配置。

      一种方法是,除了您的settings.py 之外,每个站点还有一个settings_SITENAME.py。 这些文件将具有自定义邮件服务器设置。 每个站点都有settings_local.py 是指向它自己的自定义设置文件的符号链接

      然后把这节放在settings.py的底部:

      try:                                                                                                                                                                            
          from settings_local import *                                                                                                                                                
      except ImportError:                                                                                                                                                             
          pass  
      

      现在您拥有每个站点的自定义设置

      【讨论】:

      • 用一个设置文件有什么办法吗?我需要一个 Django 实例来使用多个 SMTP 服务器进行发送。
      • 不要使用 django 电子邮件后端 - 使用较低级别的 python 库 - docs.python.org/2/library/email-examples.html
      • 请不要,大声笑。如果 settings_local 需要修改现有设置怎么办?
      • @CloudArtisans 创建一个类似 send_email 的函数,但从您的自定义电子邮件设置中提取,而不是从 django 硬编码的那些中提取。如果你有很多,你可以在字典中给它们起别名(就像 django 如何处理数据库一样)并将别名传递给你的 send_mail 函数。您唯一不能这样做的是更改 django 默认发送的电子邮件的凭据(如果 django 允许,可能需要为此进行monkeypatch 或添加自定义邮件后端)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-01
      • 2013-08-22
      • 2011-04-06
      • 2017-05-12
      • 2011-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多