Send Emails in Django

如果你沒有要自己架 mail server 的話
建議把 domain.com 掛在 Zoho 底下
用 Zoho 來「接收」郵件
另外新增一個 mailer.domain.com 掛在 Mailgun(或是 Amazon SES)底下
用 Mailgun 來「發送」郵件

ref:
https://www.zoho.com/
https://www.mailgun.com/

Configuration

Common

in settings.py

SERVER_EMAIL = 'postmaster@mailer.goeasytaxi.com'
DEFAULT_FROM_EMAIL = 'GoEasyTaxi <%s>' % (SERVER_EMAIL)
REPLY_TO_EMAIL = 'webmaster@goeasytaxi.com'

Localhost

$ sudo apt-get install sendmail
# or
# choose "Internet Site"
$ sudo apt-get install mailutils
SERVER_EMAIL = 'root@localhost'
DEFAULT_FROM_EMAIL = 'root@localhost'

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'

Amazon SES

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_HOST_USER = 'YOUR_AWS_ACCESS_KEY_ID'
EMAIL_HOST_PASSWORD = 'YOUR_AWS_SECRET_ACCESS_KEY'
EMAIL_PORT = 587
EMAIL_USE_TLS = True

Gmail

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'username@gmail.com'  # 也可以是 Google App
EMAIL_HOST_PASSWORD = 'XXX'
EMAIL_PORT = 587
EMAIL_USE_TLS = True

Mailgun

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.mailgun.org'
EMAIL_HOST_USER = 'postmaster@mailer.goeasytaxi.com'
EMAIL_HOST_PASSWORD = 'XXX'
EMAIL_PORT = 587
EMAIL_USE_TLS = True

ref:
http://thingsilearned.com/2011/06/07/mailgun-as-an-smtp-server-for-django-apps/

Zoho

Django 1.7 之前沒有 EMAIL_USE_SSL 這個設定
所以連 zoho 的 mail server 都會 timeout
你可以安裝 django-smtp-ssl

EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
EMAIL_HOST = 'smtp.zoho.com'
EMAIL_HOST_USER = 'webmaster@goeasytaxi.com'
EMAIL_HOST_PASSWORD = 'XXX'
EMAIL_PORT = 465

ref:
http://stackoverflow.com/questions/18335697/send-email-through-zoho-smtp

Usage

in views.py

from django.core.mail import EmailMessage
from django.core.mail import send_mail
from django.template.loader import render_to_string


mail_context = {
    'name': 'Vinta',
    'email': 'vinta.chen@gmail.com',
    'content': 'YOU SUCK',
}
msg = EmailMessage(
    subject='Subject',
    body=render_to_string('email/contact_email.html', mail_context),
    from_email='whatever@domain.com',
    to=['vinta.chen@gmail.com', 'someone@yahoo.com.tw'],
    headers={'Reply-To': settings.REPLY_TO_EMAIL},
)
msg.content_subtype = 'html'  # or 'plain'
msg.send()

# or

send_mail(
    'Subject',
    'Message',
    'YOUR NAME <whatever@domain.com>',
    ['vinta.chen@gmail.com', 'someone@yahoo.com.tw']
)

ref:
https://docs.djangoproject.com/en/dev/topics/email/

Testing

如果要測試 email 的 template
比較快的作法就是新增一個 test_email 的 view
然後 render email template
或是設置 EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

unit test 的話
可以用 django.core.mail.outbox
django 在跑測試的時候不會真的把 email 寄出去

ref:
https://docs.djangoproject.com/en/dev/topics/testing/overview/#email-services
http://tech.wancw.idv.tw/testing-sending-mail-in-django.html