Although Python provides a mail sending interface via the smtplib
module, Django provides a couple of light wrappers over it. These wrappers are
provided to make sending email extra quick, to help test email sending during
development, and to provide support for platforms that can't use SMTP.
コードは django.core.mail
モジュールにあります。
次の 2 文を書くことで、
from django.core.mail import send_mail
send_mail(
'Subject here',
'Here is the message.',
'from@example.com',
['to@example.com'],
fail_silently=False,
)
設定内の EMAIL_HOST
と EMAIL_PORT
で指定された SMTP ホストとポートを使用して、メールが送信されます。EMAIL_HOST_USER
と EMAIL_HOST_PASSWORD
が指定されている場合は、SMTP サーバーの認証に使われます。そして、EMAIL_USE_TLS
と EMAIL_USE_SSL
設定により、セキュアコネクションを使うかどうかをコントロールします。
注釈
django.core.mail
で送信されるメールの文字セットは、DEFAULT_CHARSET
設定の値にセットされます。
send_mail()
¶send_mail
(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)[ソース]¶In most cases, you can send email using django.core.mail.send_mail()
.
subject
、message
、from_email
、recipient_list
の 4 つの引数は必須です。
subject
: 文字列。message
: 文字列。from_email
: A string. If None
, Django will use the value of the
DEFAULT_FROM_EMAIL
setting.recipient_list
: メールアドレスを表す文字列のリスト。recipient_list
の各メンバーは、メールメッセージの "To:" フィールドで他の受信者を見ることができます。fail_silently
: A boolean. When it's False
, send_mail()
will raise
an smtplib.SMTPException
if an error occurs. See the smtplib
docs for a list of possible exceptions, all of which are subclasses of
SMTPException
.auth_user
: SMTP サーバー認証のためのユーザー名で、省略可能。指定されなかった場合、Django EMAIL_HOST_USER
設定の値を使います。auth_password
: SMTP サーバー認証のためのパスワードで、省略可能。指定されなかった場合、Django は EMAIL_HOST_PASSWORD
設定の値を使います。connection
: メール送信のために使うバックエンドで、省略可能。指定しなかった場合、デフォルトのバックエンドのインスタンスが使われます。詳しくは メールのバックエンド を参照してください。html_message
: html_message
が指定された場合、送信されるメールは multipart/alternative となり、text/plain コンテンツタイプを持つ message
と text/html コンテンツタイプを持つ html_message
を合わせ持つものになります。返り値は、送信に成功したメッセージの数です (送信されるメッセージが 1 つだけの場合もあるため、0
や 1
になることもあります)。
send_mass_mail()
¶send_mass_mail
(datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None)[ソース]¶django.core.mail.send_mass_mail()
は、大量のメール送信を扱うために用意されています。
datatuple
はメッセージの集合を表すタプルです。タプル内の各要素は、それぞれ1種類のメッセージを表すタプルであり、次の形式を持ちます。
(subject, message, from_email, recipient_list)
fail_silently
、auth_user
、auth_password
の 3 つは、send_mail()
と同じように機能します。
datatuple
に含まれる各要素は、最終的には別々のメールメッセージとなります。send_mail()
における挙動と同じく、recipient_list
内の受信者は、メールメッセージの "To:" フィールドに書かれている他の受信者のアドレスを見ることができます。
たとえば、次のコードは異なる 2 つのメッセージを 異なる 2 つの受信者のセットに送信します。しかし、メールサーバーへの接続は 1 つしか開かれません。
message1 = ('Subject here', 'Here is the message', 'from@example.com', ['first@example.com', 'other@example.com'])
message2 = ('Another Subject', 'Here is another message', 'from@example.com', ['second@test.com'])
send_mass_mail((message1, message2), fail_silently=False)
戻り値は、メッセージ送信に成功した数です。
send_mass_mail()
と send_mail()
の比較¶send_mass_mail()
と send_mail()
違いは、send_mail()
が実行されるごとに毎回接続を開くのに対して、send_mass_mail()
はすべてのメッセージに対して 1 つだけ接続を使います。これにより、send_mass_mail()
の方が若干効率がよくなっています。
mail_admins()
¶django.core.mail.mail_admins()
は、ADMINS
設定で定義されているサイト管理者 (admin) に対してメールを送信するためのショートカットです。
mail_admins()
prefixes the subject with the value of the
EMAIL_SUBJECT_PREFIX
setting, which is "[Django] "
by default.
The "From:" header of the email will be the value of the
SERVER_EMAIL
setting.
This method exists for convenience and readability.
If html_message
is provided, the resulting email will be a
multipart/alternative email with message
as the
text/plain content type and html_message
as the
text/html content type.
mail_managers()
¶django.core.mail.mail_managers()
は、mail_admins()
とほぼ同じで、MANAGERS
設定で定義されているサイト管理者 (manager) にメールを送信します。
以下の例は、john@example.com と jane@example.com に1つのメールを送信します。2人とも "To:" 内に宛先が見られます。
send_mail(
'Subject',
'Message.',
'from@example.com',
['john@example.com', 'jane@example.com'],
)
次の例は、john@example.com と jane@example.com にメールを送信しますが、受信者はどちらも個別のメールを受け取ります。
datatuple = (
('Subject', 'Message.', 'from@example.com', ['john@example.com']),
('Subject', 'Message.', 'from@example.com', ['jane@example.com']),
)
send_mass_mail(datatuple)
ヘッダインジェクション は、攻撃者が 、スクリプトで生成されたメールメッセージの "To:" と "From:" をコントロールするために、メールヘッダを挿入してしまうセキュリティ上の脆弱性です。
上述した Django のメール機能は、ヘッダー値の改行を禁止することによってヘッダインジェクションを防ぎます。 subject
、from_email
、recipient_list
のいずれかに 改行 (Unix、Windows ないし Mac のスタイル) が含まれている場合、email 関数 (例えば send_mail()
) は django.core.mail.BadHeaderError
(ValueError
のサブクラス) 投げるため、メールは送信されません。メール送信を行う関数にデータを渡す前に、開発者は責任を持ってすべてのデータを検証しておく必要があります。
If a message
contains headers at the start of the string, the headers will
be printed as the first bit of the email message.
次の例は、リクエストの POST データから subject
、message
、from_email
を取得し、それを admin@example.com に送信し、完了したら "/contact/thanks/" にリダイレクトします。
from django.core.mail import BadHeaderError, send_mail
from django.http import HttpResponse, HttpResponseRedirect
def send_email(request):
subject = request.POST.get('subject', '')
message = request.POST.get('message', '')
from_email = request.POST.get('from_email', '')
if subject and message and from_email:
try:
send_mail(subject, message, from_email, ['admin@example.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return HttpResponseRedirect('/contact/thanks/')
else:
# In reality we'd use a form class
# to get proper validation errors.
return HttpResponse('Make sure all fields are entered and valid.')
EmailMessage
クラス¶Django の send_mail()
と send_mass_mail()
関数は EmailMessage
クラスを実際に使うための小さなラッパーです。
EmailMessage
クラスの機能のすべてが send_mail()
やその他のラッパーで使用可能というわけではありません。高度な機能を使いたい場合 (例えば BCC の利用、ファイル添付やマルチパートのメールなど) EmailMessage
のインスタンスを直接作成する必要があります。
注釈
これは設計特性です。send_mail()
およびその関連の関数は、元は Django が提供した唯一のインタフェースでした。しかし、受け入れるパラメータのリストが次第に肥大化してきてしまったので、よりオブジェクト指向的な設計に移行し、元の関数は後方互換性確保のためだけに残すことになりました。
EmailMessage
はメールメッセージ本体を作成する役割を担っており、その後、メールのバックエンド がメールを送信する役目を果たします。
For convenience, EmailMessage
provides a send()
method for sending a single email. If you need to send multiple messages, the
email backend API provides an alternative.
EmailMessage
オブジェクト¶EmailMessage
クラスは、以下のパラメータで (省略可能な引数が使われた場合、その順番で) 初期化されます。全てのパラメータは省略可能で、send()
メソッドを呼ぶ前のタイミングでセットされます。
subject
: メールの件名の行。body
: 本文のテキスト。プレーンテキストのメッセージでなければなりません。from_email
: The sender's address. Both fred@example.com
and
"Fred" <fred@example.com>
forms are legal. If omitted, the
DEFAULT_FROM_EMAIL
setting is used.to
: 受信者のメールアドレスのリストまたはタプル。bcc
: メールを送信するときに "Bcc" ヘッダ内で使われるメールアドレスのリストまたはタプル。connection
: メールバックエンドのインスタンス。複数のメッセージに同一の接続を使いたいときに指定します。省略した場合、send()
が呼ばれる時に新しい接続が生成されます。attachments
: A list of attachments to put on the message. These can
be either MIMEBase
instances, or (filename,
content, mimetype)
triples.headers
: メッセージに追加するヘッダーの辞書。キーはヘッダ名、値はヘッダ値です。メールメッセージに対して適切なヘッダ名と値にするのは、呼び出す側の責任です。対応する属性は extra_headers
です。reply_to
: メールを送信するときに "Reply-To" ヘッダ内で使われる、受信者のアドレスのリストまたはタプル。例:
from django.core.mail import EmailMessage
email = EmailMessage(
'Hello',
'Body goes here',
'from@example.com',
['to1@example.com', 'to2@example.com'],
['bcc@example.com'],
reply_to=['another@example.com'],
headers={'Message-ID': 'foo'},
)
このクラスには以下のメソッドがあります。
send(fail_silently=False)
sends the message. If a connection was
specified when the email was constructed, that connection will be used.
Otherwise, an instance of the default backend will be instantiated and
used. If the keyword argument fail_silently
is True
, exceptions
raised while sending the message will be quashed. An empty list of
recipients will not raise an exception. It will return 1
if the message
was sent successfully, otherwise 0
.
message()
constructs a django.core.mail.SafeMIMEText
object (a
subclass of Python's MIMEText
class) or a
django.core.mail.SafeMIMEMultipart
object holding the message to be
sent. If you ever need to extend the
EmailMessage
class, you'll probably want to
override this method to put the content you want into the MIME object.
recipients()
は、to
、cc
、bcc
のいずれかの属性に記録されている、メッセージの全ての受信者のリストを返します。サブクラス化するときには、メッセージの送信時に SMTP サーバが受信者の完全な一覧を必要とするため、このメソッドもオーバーライドする必要があります。クラス内で受信者を指定する別の方法を追加する場合は、このメソッドからも返される必要があります。
attach()
は新しい添付ファイルを作成し、メッセージに追加します。attach()
を呼ぶには2 つの方法があります。
You can pass it a single argument that is a
MIMEBase
instance. This will be inserted directly
into the resulting message.
もしくは、attach()
の 3 つの引数を引き渡します: filename
、content
、mimetype
です。filename
は、メール内に表示される添付ファイルの名前です。content``は、添付ファイル内に含まれるデータです。``mimetype
は添付ファイルに対する MIME タイプで、省略可能です。mimetype
を省略した場合、MIME コンテンツタイプは添付ファイルのファイル名から推測されます。
例:
message.attach('design.png', img_data, 'image/png')
If you specify a mimetype
of message/rfc822, it will also
accept django.core.mail.EmailMessage
and
email.message.Message
.
For a mimetype
starting with text/, content is expected to
be a string. Binary data will be decoded using UTF-8, and if that fails,
the MIME type will be changed to application/octet-stream and
the data will be attached unchanged.
In addition, message/rfc822 attachments will no longer be base64-encoded in violation of RFC 2046#section-5.2.1, which can cause issues with displaying the attachments in Evolution and Thunderbird.
attach_file()
creates a new attachment using a file from your
filesystem. Call it with the path of the file to attach and, optionally,
the MIME type to use for the attachment. If the MIME type is omitted, it
will be guessed from the filename. You can use it like this:
message.attach_file('/images/weather_map.png')
For MIME types starting with text/, binary data is handled as in
attach()
.
メール内にコンテンツの複数のバージョンを入れておくのが便利です; 古典的な手法では、メッセージをテキストと HTML の両方のバージョンで送信します。 Django のメールのライブラリで、EmailMultiAlternatives
を使ってこれを実現できます。この EmailMessage
のサブクラスには、attach_alternative()
があり、E メール内のメッセージ本文の別バージョンを追加することができます。(クラスの初期化を含む) 他のメソッドは EmailMessage
から直接継承されます。
テキストと HTML の組み合わせを送るには、以下のように書きます:
from django.core.mail import EmailMultiAlternatives
subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
text_content = 'This is an important message.'
html_content = '<p>This is an <strong>important</strong> message.</p>'
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
デフォルトでは、EmailMessage
内の body
パラメータの MIME タイプは "text/plain"
です。この設定だとメールクライアントにかかわらず全ての受信者がメールを読むことができるので、このままにしておくのが実用的です。しかし、受信者が代替のコンテンツタイプを扱えることが確かな場合には、EmailMessage
の content_subtype
属性を使ってメインのコンテンツタイプを変更することもできます。主なタイプは常に "text"
ですが、サブタイプを変更することができます。例えば:
msg = EmailMessage(subject, html_content, from_email, [to])
msg.content_subtype = "html" # Main content is now text/html
msg.send()
実際のメール送信は、メールバックエンドによって処理されます。
メールバックエンドのクラスには以下のメソッドがあります:
open()
は、長寿命のメール送信の接続をインスタンス化します。close()
は、現在のメール送信の接続を閉じます。send_messages(email_messages)
sends a list of
EmailMessage
objects. If the connection is
not open, this call will implicitly open the connection, and close the
connection afterward. If the connection is already open, it will be
left open after mail has been sent.コンテキストマネジャーとしても使うことができ、必要に応じて自動的に open()
と close()
呼びます:
from django.core import mail
with mail.get_connection() as connection:
mail.EmailMessage(
subject1, body1, from1, [to1],
connection=connection,
).send()
mail.EmailMessage(
subject2, body2, from2, [to2],
connection=connection,
).send()
django.core.mail
内の get_connection()
関数は、利用可能なメールバックエンドのインスタンスを返します。
デフォルトでは、get_connection()
を呼び出すと EMAIL_BACKEND
内で指定されたメールバックエンドのインスタンスを返します。backend
引数を指定した場合、そのバックエンドがインスタンス化されます。
fail_silently
引数は、バックエンドがエラーをどのように扱うかをコントロールします。fail_silently
が True の場合、メール送信プロセスの間に発生した例外は何の通知もされずに無視されます。
他の全ての引数は、メールバックエンドのコンストラクタに直接引き渡されます。
Django には複数のメール送信バックエンドを付属しています。SMTP バックエンド (デフォルトです) を除いて、これらのバックエンドはテストと開発のみで役立ちます。特別なメール送信が必要な場合には、独自のメールバックエンドを記述する を参照してください。
backends.smtp.
EmailBackend
(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)¶デフォルトのバックエンド。メールは SMTP サーバを通して送信されます。
引数が None
の場合、各引数に対する値は、以下のそれぞれの設定から取得されます。
host
: EMAIL_HOST
port
: EMAIL_PORT
username
: EMAIL_HOST_USER
password
: EMAIL_HOST_PASSWORD
use_tls
: EMAIL_USE_TLS
use_ssl
: EMAIL_USE_SSL
timeout
: EMAIL_TIMEOUT
ssl_keyfile
: EMAIL_SSL_KEYFILE
ssl_certfile
: EMAIL_SSL_CERTFILE
SMTP バックエンドは、Django によって継承されるデフォルトの構成です。明示的に指定したい場合は、設定内で以下の通り記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
指定しなかった場合は、デフォルトの timeout
は socket.getdefaulttimeout()
によって指定されたものになり、デフォルトは None
(タイムアウトなし) になります。
実際のメールを送信する代わりに、コンソールバックエンドは単に標準出力に送信されるメールを書き込みます。 デフォルトでは、コンソールバックエンドは stdout
に書き込みます。 接続を構築するときに stream
キーワード引数を指定することで、別のストリーム的なオブジェクトを使用できます。
このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
このバックエンドはプロダクトでの使用を想定していません -- 開発中の利便性のために提供されています。
ファイルバックエンドは、メールをファイルに書き込みます。新しいファイルは、このバックエンド上で開いたそれぞれの新しいセッションに対して作成されます。ファイルが書き込まれるディレクトリは、 get_connection()
で 接続を生成したときに EMAIL_FILE_PATH
設定ないし file_path
キーワードから取得されます。
このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location
このバックエンドはプロダクトでの使用を想定していません -- 開発中の利便性のために提供されています。
'locmem'
バックエンドは、 django.core.mail
モジュールの特別な属性内にメッセージを保持します。outbox
属性は最初のメッセージが送信されるときに生成されます。送信される書くメッセージに対する EmailMessage
インスタンスのリストです。
このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
このバックエンドはプロダクトでの使用を想定していません -- 開発とテストにおける利便性のために提供されています。
Django's test runner automatically uses this backend for testing.
名前が示すように、ダミーバックエンドはメッセージに何もしません。このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
このバックエンドはプロダクトでの使用を想定していません -- 開発中の利便性のために提供されています。
メール送信の方法を変更する必要がある場合、独自のメールバックエンドを記述することができます。設定ファイル内の EMAIL_BACKEND
設定が独自のバックエンドのクラスへの Python のインポートパスとなります。
独自のメールバックエンドは、django.core.mail.backends.base
にある BaseEmailBackend
をサブクラス化して作ります。独自のメールバックエンドには send_messages(email_messages)
メソッドを実装する必要があります。このメソッドは EmailMessage
インスタンスのリストを受け取り、送信に成功したメッセージの数を返します。バックエンドに持続瀬的なセッションや接続の概念がある場合は、open()
メソッドと close()
メソッドも実装する必要があります。実装のリファレンスについては smtp.EmailBackend
を参照してください。
SMTP 接続 (またはその他のネットワーク接続) の確立とクローズは、負荷の高い処理です。 送信するメールがたくさんある場合は、メールを送信するたびに接続の生成と破棄を繰り返すのではなく、SMTP 接続を再利用する方が効率的です。
メールバックエンドに接続を再利用するよう通知するには、2 つの方法があります。
1つ目は、send_messages()
メソッドを使う方法です。send_messages()
は EmailMessage
インスタンス (ないしサブクラス) のリストを取得し、この全てを単一の接続を使って送信します。
例えば、定期的なメール送信を表す EmailMessage
オブジェクトのリストを返す get_notification_email()
と呼ばれる関数がある場合、send_messages を 1度呼び出すだけでこれらのメールを送信することができます:
from django.core import mail
connection = mail.get_connection() # Use default email connection
messages = get_notification_email()
connection.send_messages(messages)
この例では、send_messages()
を呼び出してバックエンドの接続を開き、メッセージのリストを送信した後、再び接続を閉じています。
2つ目のアプローチは、メールバックエンドの open()
メソッドと close()
メソッドを使って手動で接続をコントロールする方法です。send_messages()
は、すでに接続が開いている場合、自動で接続を開いたり閉じたりはしません。手動で接続を開いた場合、閉じるタイミングを自分でコントロールできます。たとえば、次のように書くことができます。
from django.core import mail
connection = mail.get_connection()
# Manually open the connection
connection.open()
# Construct an email message that uses the connection
email1 = mail.EmailMessage(
'Hello',
'Body goes here',
'from@example.com',
['to1@example.com'],
connection=connection,
)
email1.send() # Send the email
# Construct two more messages
email2 = mail.EmailMessage(
'Hello',
'Body goes here',
'from@example.com',
['to2@example.com'],
)
email3 = mail.EmailMessage(
'Hello',
'Body goes here',
'from@example.com',
['to3@example.com'],
)
# Send the two emails in a single call -
connection.send_messages([email2, email3])
# The connection was already open so send_messages() doesn't close it.
# We need to manually close the connection.
connection.close()
Django に電子メールをまったく送信させたくない場合もあるでしょう。たとえば、ウェブサイトの開発中に数千通のメールを送信したくはないでしょう。しかし、適切な条件で適切な人々にメールが送信され、これらのメールが正しい内容を含んでいるか検証したいことがあるかもしれません。
The easiest way to configure email for local development is to use the
console email backend. This backend
redirects all email to stdout
, allowing you to inspect the content of mail.
ファイル メールバックエンドも開発に役立ちます -- このバックエンドは全ての SMTP 接続をファイルにダンプし、都合の良いときに調べられるようにします。
Another approach is to use a "dumb" SMTP server that receives the emails locally and displays them to the terminal, but does not actually send anything. The aiosmtpd package provides a way to accomplish this:
python -m pip install aiosmtpd
python -m aiosmtpd -n -l localhost:8025
This command will start a minimal SMTP server listening on port 8025 of
localhost. This server prints to standard output all email headers and the
email body. You then only need to set the EMAIL_HOST
and
EMAIL_PORT
accordingly. For a more detailed discussion of SMTP
server options, see the documentation of the aiosmtpd module.
アプリケーションでのメール送信のユニットテストについては、テストのドキュメントの Email services セクションを参照してください。
2022年6月01日