Django:在视图中设置电子邮件设置

Django: Set E-Mail settings in view

我正在尝试使用来自 Google 的 SMTP 发送电子邮件。我已经发送了一封电子邮件,将设置变量放在文件 "settings.py" 中,但我需要在视图中配置这些变量并使用我的 "Config" 模型设置它们。

这是我的模型代码:

class Config(models.Model):
    email_sender    = models.CharField(max_length = 100, default = '', blank = True)
    email_password  = models.CharField(max_length = 30, default = '', blank = True)
    smtp_server     = models.CharField(max_length = 100, default = '', blank = True)
    smtp_port       = models.PositiveIntegerField(default = 587, blank = True)

这是我的查看代码:

def send_custom_mail(request):
    config = Config.objects.get(pk = 1)
    EMAIL_HOST = config.smtp_server
    EMAIL_PORT = config.smtp_port
    EMAIL_HOST_USER = config.email_sender
    EMAIL_HOST_PASSWORD = config.email_password
    EMAIL_USE_TLS = True
    DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
    subject = 'test'
    msg = '<p>Test: <strong>Mensaje</strong>></p>'
    mail_from = config.email_sender
    mail_to = ['{}'.format(email)]
    from django.core.mail import EmailMessage
    email2send  = EmailMessage(subject, msg, mail_from, to=mail_to)
    email2send.content_subtype = "html"  # Main content is now text/html
    email2send.send()

我的问题:当我在视图中设置变量时,电子邮件没有发送。

我需要动态配置这些变量,所以我不能把它写在 setting.py 文件中。

我找到了这个解决方案,但我不知道它是否是解决这个问题的最佳方法:

使用这个:https://docs.djangoproject.com/en/1.11/_modules/django/test/utils/#override_settings

在我看来,我重写了设置变量:

from django.core.mail import EmailMessage
from django.test.utils import override_settings

@override_settings(EMAIL_HOST = Config.objects.get(pk = 1).smtp_server)
@override_settings(EMAIL_HOST_USER = Config.objects.get(pk = 1).email_sender)
@override_settings(EMAIL_PORT = Config.objects.get(pk = 1).smtp_port)
def send_custom_mail(request):
subject = 'test'
    msg = 'Test:Mensaje'
    mail_to = ['test@test.com']
    email2send  = EmailMessage(subject, msg, to=mail_to)
    email2send.content_subtype = "html"  # Main content is now text/html
    email2send.send()

在这个方法中,我使用 "django.test.utils" 将装饰器“@override_settings()”放在 "send_custom_mail" 函数之前。它覆盖设置并让我从保存在名为 Config 的模型中的邮件发送电子邮件。

实际上,我不确定这是否是最好的方法,因为 "django.test" 模块用于单元测试,但我想分享我的解决方案。

我对必须覆盖视图中的设置感到有点困惑;以前从未见过它的用例。

我通常使用的策略是回退到较低级别的函数。

我建议您可以使用 send_mail() 函数和 get_connection().

来实现您似乎需要的功能

尚未测试此代码,但认为它看起来像这样:

from django.core import mail

connection = mail.get_connection(
    host = config.smtp_server,
    port = config.smtp_port,
    username = config.email_sender,
    password = config.email_password ,
    (... etc etc ...)
)

# Manually open the connection
connection.open()

# Send the message
subject = 'test'
msg = 'Test:Mensaje'
mail_to = ['test@test.com']
email2send  = EmailMessage(
    subject, 
    msg, t
    o=mail_to
    connection=connection
)

# Send the email using the custom connection
email2send.send()

# Close the connection
connection.close()

(请注意 connection=connection 当 EmailMessage 首次设置为通过自定义连接发送电子邮件时。)

Django Email Backends 文档很好地解释了这一点,这似乎是比覆盖设置更直接的方法。

def email_sending(mail_subject, message,to, mail_obj=None):
if not mail_obj:
    try:

        mail_obj = AdminEMailsModel.objects.filter(default_email=True)[0]

    except Exception as e:
        print(e)
        try:
            if not mail_obj:
                mail_obj= AdminEMailsModel.objects.all()[0]

        except Exception as e:
            print(e)
            return
backend = EmailBackend(host=mail_obj.host_address, port=mail_obj.port_no, username=mail_obj.email,
                       password=mail_obj.password, use_tls=mail_obj.use_tls, fail_silently=False)
email = EmailMultiAlternatives(
    mail_subject, message, from_email=mail_obj.email, to=to, connection=backend
)

email.attach_alternative(message, 'text/html')
email.send()

return

directly you can call this function whenever you need to send an email to register email if this code is usefull to you please give up vote