Django18初体验


1463 浏览 5 years, 2 months

16 邮件配置

版权声明: 转载请注明出处 http://www.codingsoho.com/

https://docs.djangoproject.com/en/1.8/topics/email/

在配置文件添加邮件相关的配置

settings.py

EMAIL_HOST = 'smtp.sina.com'
EMAIL_HOST_USER = 'hebinn2004@sina.com'
EMAIL_HOST_PASSWORD = 'yourpassword'
EMAIL_PORT = 25
EMAIL_USE_TLS = True

views.py

from django.conf import settings
from django.core.mail import send_mail

def contact(request):
    title = 'Contact Us'
    title_align_center = True
    form = ContactForm(request.POST or None)
    if form.is_valid():
        form_email = form.cleaned_data.get("email")
        form_message = form.cleaned_data.get("message")
        form_full_name = form.cleaned_data.get("full_name")
        subject = 'Site contact form'
        from_email = settings.EMAIL_HOST_USER
        to_email = [from_email, 'youotheremail@email.com']
        contact_message = "%s: %s via %s"%( 
                form_full_name, 
                form_message, 
                form_email)
        some_html_message = """
        <h1>hello</h1>
        """
        send_mail(subject, 
                contact_message, 
                from_email, 
                to_email, 
                html_message=some_html_message,
                fail_silently=True)
    context = {
        "form": form,
        "title": title,
        "title_align_center": title_align_center,
    }
    return render(request, "forms.html", context)

阿里云上的端口有限制,25端口不能用,可参考备份当前博客系统的数据库和媒体文件文中配置方法

所以我们改用465端口(SMTPS),实现上要用SMTP_SSL函数取代SMTP

查看代码

class EmailBackend(BaseEmailBackend):
    def __init__(self, host=None, port=None, username=None, password=None,
                 use_tls=None, fail_silently=False, use_ssl=None, timeout=None,
                 ssl_keyfile=None, ssl_certfile=None,
                 **kwargs):
        super(EmailBackend, self).__init__(fail_silently=fail_silently)
        self.host = host or settings.EMAIL_HOST
        self.port = port or settings.EMAIL_PORT
        self.username = settings.EMAIL_HOST_USER if username is None else username
        self.password = settings.EMAIL_HOST_PASSWORD if password is None else password
        self.use_tls = settings.EMAIL_USE_TLS if use_tls is None else use_tls
        self.use_ssl = settings.EMAIL_USE_SSL if use_ssl is None else use_ssl                                      # (1)
        self.timeout = settings.EMAIL_TIMEOUT if timeout is None else timeout
        self.ssl_keyfile = settings.EMAIL_SSL_KEYFILE if ssl_keyfile is None else ssl_keyfile
        self.ssl_certfile = settings.EMAIL_SSL_CERTFILE if ssl_certfile is None else ssl_certfile
        if self.use_ssl and self.use_tls:
            raise ValueError(
                "EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive, so only set "
                "one of those settings to True.")
        self.connection = None
        self._lock = threading.RLock()
    def open(self):
        """
        Ensures we have a connection to the email server. Returns whether or
        not a new connection was required (True or False).
        """
        if self.connection:
            # Nothing to do if the connection is already open.
            return False
        connection_class = smtplib.SMTP_SSL if self.use_ssl else smtplib.SMTP                 # (2)
        # If local_hostname is not specified, socket.getfqdn() gets used.
        # For performance, we use the cached FQDN for local_hostname.
        connection_params = {'local_hostname': DNS_NAME.get_fqdn()}
        if self.timeout is not None:
            connection_params['timeout'] = self.timeout
        if self.use_ssl:
            connection_params.update({
                'keyfile': self.ssl_keyfile,
                'certfile': self.ssl_certfile,
            })
        try:
            self.connection = connection_class(self.host, self.port, **connection_params)
            # TLS/SSL are mutually exclusive, so only attempt TLS over                  # (3)
            # non-secure connections.
            if not self.use_ssl and self.use_tls:
                self.connection.ehlo()
                self.connection.starttls(keyfile=self.ssl_keyfile, certfile=self.ssl_certfile)
                self.connection.ehlo()
            if self.username and self.password:
                self.connection.login(self.username, self.password)
            return True
        except smtplib.SMTPException:
            if not self.fail_silently:
                raise
  • (1) 可以在setting里指定是否采用SSL,因为465端口就是SSL
  • (2) 如果SSL已设置,那么会采用smtplib.SMTP_SSL函数
  • (3) TLS/SSL are mutually exclusive, so only attempt TLS over 这两个不能同时设置

尝试过的几种配置方式

测试代码

from django.core.mail import send_mail
send_mail('subject', 
        'message', 
        'hebinn2004@sina.com', 
        ['hebinn@163.com',], 
        html_message="<h1>hello</h1>",
        fail_silently=False)

配置1

EMAIL_PORT = 25

配置2:

EMAIL_PORT = 25
EMAIL_USE_TLS = True

配置3:

EMAIL_PORT = 465
EMAIL_USE_SSL = True