revision-up-to: | 17812 (1.4) |
---|
Python の smtplib
モジュール を使えば、比較的簡単にメールを送信できます
が、 Django ではこのライブラリへの軽量ラッパを二つ用意しています。これらのラッパ
ではメールの送信を極めて素早くおこなえ、開発時のテストメールの送信を簡単にでき、
SMTPを使えないプラットフォームにも対応しています。
コードは: django.core.mail
にあります。
二行だけです:
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 サーバの認証に使います。
また、SMTP サーバとの接続に TLS を使うかどうかを
EMAIL_USE_TLS
で設定できます。
Note
django.core.mail
で送信されるメールの文字セットは
DEFAULT_CHARSET
設定の値に設定されます。
send_mail
(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None)¶メールを送信する最も簡単な方法は django.core.mail.send_mail()
です。
subject
, message
, from_email
および recipient_list
は必須の
パラメタです。
subject
: 文字列です。message
: 文字列です。from_email
: 文字列です。recipient_list
: 文字列からなるリストで、各々がメールアドレ
スを表します。 recipient_list
に入っているユーザは、お互いに他のユー
ザをメールの “To:” フィールドで見られます。fail_silently
: ブール型の値です。 False
なら send_mail
は
smtplib.SMTPException
例外を出すようになります。
送出されうる例外のリストは smtplib
ドキュメントを参照してくださ
い。いずれの例外も SMTPException
のサブクラスです。auth_user
: オプションです。 SMTP サーバでの認証に使うユーザ名です。
この値を指定しなければ、 Django は EMAIL_HOST_USER
設定を使います。auth_password
: オプションです。 SMTP サーバでの認証に使うパスワー
ドです。この値を指定しなければ、 Django は EMAIL_HOST_PASSWORD
設
定を使います。connection
: オプションです。メール送信に使うバックエンドです。
明示しなければデフォルトのバックエンドが使われます。詳細はドキュメントの
Email backends を参照してください。send_mass_mail
(datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None)¶django.core.mail.send_mass_mail()
は一括メール (mass email) の送信
用の関数です。この関数の定義は以下の通りです
datatuple
はタプルで、各要素は以下の形式になっています:
(subject, message, from_email, recipient_list)
fail_silently
, auth_user
および auth_password
は
send_mail()
と同じです。
datatuple
の各要素ごとに個別のメールメッセージを作成して送信します。
send_mail()
と同様、同じ recipient_list
に入ってい
る受信者は、他の受信者を “To:” フィールドで見られます。
例えば下記のコードでは、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_mail()
は実行の度にメールサーバに
接続するのに対し、 send_mass_mail()
は全てのメッセージの
送信に一つの接続を使う点です。このため、 send_mass_mail()
の方が少しだけ効率的です。
mail_admins
(subject, message, fail_silently=False, connection=None, html_message=None)¶django.core.mail.mail_admins()
は ADMINS
に書かれたサイト管理者
へのメール送信を行うためのショートカットです。
mail_admins()
はサブジェクトの先頭に EMAIL_SUBJECT_PREFIX
の
設定値を付加します。デフォルトは "[Django] "
です。
メールの “From:” ヘッダには SERVER_EMAIL
の設定値が入ります。
このメソッドは利便性と可読性のために用意されています。
リリースノートを参照してください
html_message
が指定されているなら、結果のメールは
multipart/alternative メールになります。 text/plain
タイプの message
と text/html タイプの html_message
から
なります。
mail_managers
(subject, message, fail_silently=False, connection=None, html_message=None)¶django.core.mail.mail_managers()
は mail_admins()
と同じですが、メールを
MANAGERS
設定に書かれたサイトマネジャに送信します。
以下の例は、単一のメールを john@example.com と jane@example.com に送信 します。両方の宛先が “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 形式の) 改行を含む場
合、メール送信関数 ( send_mail()
など) は
django.core.mail.BadHeaderError
例外 (ValueError
のサブクラス) を送
出します。このため、メールは送信されません。メール送信関数に渡すデー
タの検証はユーザに任されています。
message
の文字列の先頭にヘッダが入っている場合、ヘッダは単にメッセー
ジ本文の先頭部分として出力されます。
以下に示すのは、 subject
, message
および from_email
をリクエス
トの POST データから受け取り、メールを admin@example.com に送信し、終了した
ら “/contact/thanks/” にリダイレクトする例です:
from django.core.mail import send_mail, BadHeaderError
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:
# 実際にはフォームクラスを使って適切な検証エラーを
# 取得するべきでしょう。
return HttpResponse('Make sure all fields are entered and valid.')
Django の send_mail()
および
send_mass_mail()
関数は、実際には
EmailMessage
クラスに対して薄いラッパをかぶせたものに
すぎません。
send_mail()
をはじめとしたラッパ関数から利用できる
機能は、 EmailMessage
クラスで提供している全ての
機能をカバーしているわけではありません。BCC への宛先を指定やファイルの添付、
マルチパート形式メールの送信などを行いたい場合には、
EmailMessage
インスタンスを直接生成する必要があり
ます。
Note
send_mail()`()
がこのような、いささかややこしい仕様
なのは、設計上の事情によるものです。 send_mail()`()
などの関数はもともと単なる Django 向けの単純なメールインタフェースでしか
ありませんでした。その後、指定できるパラメタが少しづつふえてきたのです。
今となっては、メールメッセージを扱うためのよりオブジェクト指向の設計に移行
して、 send_mail()`()
は互換性のためだけにおいておく
方が有意義でしょう。
EmailMessage
はメールメッセージ自体の生成に関わり
ます。 メールバックエンド は、メールの送信に関わり
ます。
便宜上、 EmailMessage
は単純な send()
メソッド
を単一のメールを送信するために提供しています。複数のメッセージを送りたいときは、
メールバックエンドAPIは 他の手段を提供しています 。
EmailMessage
¶EmailMessage
クラスは以下のパラメタ (固定引数を使
う場合には以下に示す順番に指定します) で初期化します。パラメタは全て省略可能
で、 send()
メソッドを呼び出す前であればいつでも設定しなおせます。
cc
が追加されました。subject
: メールの題名です。body
: メール本文です。平文テキストのメッセージでなければなりません。from_email
: 送信者のアドレスです。 fred@example.com
形式でも
Fred <fred@example.com>
形式でもかまいません。省略すると、
DEFAULT_FROM_EMAIL
の設定値を使います。to
: 受信者アドレスのリストまたはタプルです。bcc
: メールを送信する際に “Bcc” ヘッダに指定するアドレスのリストconnection
: メールバックエンドのインスタンスです。一つの SMTP 接
続を使い回して複数のメッセージを送信したい場合に指定します。この引数を省略する
と、 send()
を呼び出す瞬間に新しい接続を生成します。attachments
: メールに添付するデータのリストです。リストの各要素は、
email.MIMEBase.MIMEBase
のインスタンスか、
(filename, content, mimetype)
からなるタプルです。headers
: メッセージに追加するヘッダの辞書です。ヘッダ名をキーに、
ヘッダ値を値にします。このパラメタを使うのなら、指定したヘッダがメー
ルメッセージ中で正しいヘッダとして扱われるように気をつけねばなりませ
ん。cc
: 受信者アドレスのリストまたはタプルです。メール送信時の “Cc” ヘッダに
使われます。例を示します:
email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
['to1@example.com', 'to2@example.com'], ['bcc@example.com'],
headers = {'Reply-To': 'another@example.com'})
EmailMessage
クラスのインスタンスには以下のようなメソッドがあります:
send(fail_silently=False)
メソッドはメッセージを送信します。メールが作成さ
れたときに接続が指定されれば、その接続が使われます。接続がなければ、デフォルト
バックエンドのインスタンスが生成され、使われます。 fail_silently
を
True
にすると、メッセージ送信に失敗した場合に例外を送出します。
message()
は django.core.mail.SafeMIMEText
クラス (Python の
email.MIMEText.MIMEText
クラスのサブクラス) または
django.core.mail.SafeMIMEMultipart
クラスのインスタンスを生成します。
このオブジェクトには送信するメッセージが入っています。
EmailMessage
クラスを拡張する必要がある場合、
おそらくこのメソッドをオーバライドして、所望の内容を MIME オブジェクト内に
配置することになるでしょう。
recipients()
はメッセージの全ての宛先からなるリストを返します。この
宛先リストは、 to
と bcc
に指定した全ての宛先が入ります。
EmailMessage
をサブクラス化する際、このメソッドも
オーバライドする必要があるかもしれません。というのも、 SMTP サーバはメッセージ
送信時に全ての宛先を知る必要があり、全ての宛先はこのメソッドを介して返さねば
ならないからです。
attach()
を呼び出すと、新たなファイル添付用パートを生成してメッセー
ジに追加します。 attach()
の呼び出しかたは 2 通りあります:
attach()
に引数を一つだけ指定し、 email.MIMEBase.MIMEBase
のインスタンスを渡します。このインスタンスの内容は最終的なメッセージ
に直接挿入されます。
別の方法として、 attach()
に 3 つの引数、 filename
,
content
および mimetype
を渡します。 filename
は添付する
ファイルの名前で、これはメール中で表示される添付ファイルの名前になり
ます。 content
は添付パート中に入るデータで、 mimetype
は添
付内容の MIME タイプです。 mimetype
を省略すると、ファイル名を元
に推測を行います。
例を示します:
message.attach('design.png', img_data, 'image/png')
attach_file()
を呼び出すと、ファイルシステム上のファイルから添付パー
トを生成します。 attach_file()
の引数には添付したいファイルのパスを
指定します。オプションとして、添付ファイルの MIME タイプも指定できます。
MIME タイプを省略すると、ファイル名をもとに推測を行います。簡単な使い方
を示すと、以下のようになります:
message.attach_file('/images/weather_map.png')
メールの内容をいくつかのバージョンに分けて送信すると便利な場合があります。
古典的な例でいえば、テキスト形式と HTML 形式の両方でメールを送信するような
場合です。
複数バージョンのメールを同時に送るには、 EmailMultiAlternatives
クラス
を使います。このクラスは EmailMessage
のサブクラスで、
attach_alternative()
メソッドを使ってメールのメッセージ本文に別のバージョ
ンの本文を追加できます。 attach_alternative()
以外は、(クラスをインスタ
ンス化するときの初期化メソッドも含めて) 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"
です。実践的には、このパラメタは変更せずにおいた
方がよいでしょう。なぜなら、メールを受信した人が使っているメールクライアントソフ
トに関係なくメッセージを読めるよう保証できるからです。とはいえ、メールの読み手
が拡張コンテンツ形式 (alternative content type) のメッセージを扱えると分かっ
ている場合には、 EmailMessage
の content_subtype
属性を使って、主メッセージのコンテンツタイプを変更できます。メールのメジャー
コンテンツタイプは常に "text"
ですが、サブタイプは以下のように変更できます:
msg = EmailMessage(subject, html_content, from_email, [to])
msg.content_subtype = "html" # メインのコンテンツは text/html になります。
msg.send()
リリースノートを参照してください
メールを送るのは、実際にはメールバックエンドが扱っています。
メールバックエンドクラスには以下のようなメソッドがあります:
open()
永続するメール送信接続をインスタンス化します。close()
現在のメール送信接続を閉じます。send_messages(email_messages)
EmailMessage
オブジェクトを送信します。接続が開かれていないときは暗黙的に接続が開かれ、
メール送信後に閉じられます。 接続がすでに開かれているときは、メール送信後も
接続は開かれたままになります。django.core.mail
の get_connection()
関数はメールバックエンドの
インスタンスを、あなたが使えるように返します。
get_connection
(backend=None, fail_silently=False, *args, **kwargs)¶デフォルトで get_connection()
は EMAIL_BACKEND
で指定された
メールバックエンドのインスタンスを返します。引数 backend
を指定した
場合は、そのバックエンドのインスタンスを返します。
fail_silently
引数は、バックエンドがエラーを扱うかどうかを指定できます。
fail_silently
が True のときは、メール送信プロセス中の例外が無視されます。
それ以外の引数は、メールバックエンドのコンストラクタに直接渡されます。
いくつかのメール送信バックエンドが Django には付属しています。SMTPバックエンド (デフォルト)以外のバックエンドは、テストと開発時にのみ有効です。特別なメール送信 が必要な場合は、 自分でメールバックエンドを書いてください 。
これはデフォルトのバックエンドです。メールは SMTP サーバを通して送信されます。
サーバのアドレスと認証情報は EMAIL_HOST
、 EMAIL_PORT
、
EMAIL_HOST_USER
、 EMAIL_HOST_PASSWORD
と
EMAIL_USE_TLS
設定を設定ファイルに書いてください。
SMTP バックエンドは古くから Django のデフォルトです。 明示的に指定したいときは以下のように設定ファイルに書いてください:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
SMTPConnection objects
先のバージョン 1.2 では、 Django は SMTPConnection
クラスを提供していました。このクラスは SMTP を直接制御してメールを送信する方法
を提供します。このクラスは、汎用のメールバックエンドAPIが採用さたので廃止され
ました。
後方互換性のために SMTPConnection
は
SMTP バックエンドの別名として django.core.mail
で依然使えます。
実際にメールを送信する代わりに、コンソールバックエンドはただメールを書く
だけです。コンソールバックエンドに書かれたメールは標準出力に送られます。
デフォルトでは、コンソールバックエンドは stdout
に書きます。
接続を構成するときに stream
キーワード引数を与えると、他のストリームなどの
オブジェクトも使えます。
コンソールバックエンドを指定するには以下を設定ファイルに記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
コンソールバックエンドは製品での使用を意図していません。開発時に使える、利便性の ため提供されるものです。
ファイルバックエンドはメールをファイルに書き込みます。ファイルバックエンドが
新しいセッションを開く度に、新しいファイルは作られます。ファイルが書き込まれる
ディレクトリは、 EMAIL_FILE_PATH
設定か file_path
キーワードの
どちらかで決められます。これは get_connection()
との接続
が作成されるときに決まります。
ファイルバックエンドを指定するには以下を設定ファイルに記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/app-messages' # 適切な値に変えてください。
ファイルバックエンドは製品での使用を意図していません。開発時に使える、利便性の ため提供されるものです。
'locmem'
バックエンドはメッセージを django.core.mail
モジュールの特殊な
属性に格納します。 outbox
属性は最初のメッセージが送られたときに作られます。
EmailMessage
インスタンスのリストがそれぞれのメッセージ
として送られます。
メモリバックエンドを指定するには以下を設定ファイルに記述してください:
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
メモリバックエンドは製品での使用を意図していません。開発やテスト時に使える、 利便性のため提供されるものです。
名前が示すように、ダミーバックエンドはメッセージに対して何もしません。
ダミーバックエンドを指定するには以下を設定ファイルに記述してください:
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つあります。
第一に、 send_messages()
メソッドを使う方法があります。 send_messages()
は EmailMessage
インスタンス (もしくはサブクラス) の
リストを受け取り、1つの接続を使ってそれら全てを送信します。
例えば get_notification_email()
関数を使えば、定期送信するメールを
EmailMessage
オブジェクトのリストで返してくれるので、
そのまま send_messages を使って送信することができます:
from django.core import mail
connection = mail.get_connection() # デフォルトのメール接続を使います。
messages = get_notification_email()
connection.send_messages(messages)
この例では、 send_messages()
は接続をバックエンドで開き、メッセージのリスト
を送信し、さらに接続を切断します。
2つ目の方法はメールバックエンドの open()
と close()
メソッドを手動で使っ
て接続をコントロールすることです。 send_sessages()
では手動で接続を開いたり
閉じたりコントロールできません。すでに接続が開かれているときは手動で接続を開いた
ということなので、閉じるタイミングをコントロールできます:
from django.core import mail
connection = mail.get_connection()
# 手動で接続を開きます。
connection.open()
# メールメッセージを作成します。さっき作った接続で使います。
email1 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
['to1@example.com'], connection=connection)
email1.send() # Send the email
# さらに二つ作成します。
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'])
# 二つのメールを一つの呼び出しで送信します。
connection.send_messages([email2, email3])
# send_messages() が接続を閉じなかったので未だに開かれています。
# なので手動で閉じる必要があります。
connection.close()
Django に一切のメール送信をしてほしくないときがあります。例えば、 Web サイトの 開発をしているとき、何千ものメールを送信してほしくないと思います。しかし適切な 条件の下で適切な相手に、正しい内容のメールを送るのを認めたい場合があるかもしれま せん。
プロジェクトのメールの扱いをテストする最も簡単な方法は console
を使うこと
です。このバックエンドはすべてのメールを標準出力にリダイレクトします。これで
メールの内容を検査することができます。
file
メールバックエンドも開発時には使えます。このバックエンドはすべての
SMTP コネクションのコンテンツをファイルにダンプします。なので暇なときに検査
できます。
他にも “無口な (dumb)” SMTP サーバを使う方法があります。この SMTP サーバはロー カルでメールを受け取って端末に表示しまが、送信はなにもしません。 Python のビル ドインで、1つのコマンドでできます:
python -m smtpd -n -c DebuggingServer localhost:1025
このコマンドはローカルホストのリスニングポート 1025 で SMTP サーバ を開始しま
す。このサーバはすべてのメールのヘッダ、ボディーを標準出力に書き出します。そし
て必要なのは EMAIL_HOST
と EMAIL_PORT
をそれらしく設定し
ます。以上です。
ローカルでのメールの処理やテストの詳細については、 Python ドキュメントの
smtpd
を参照してください。
SMTPConnection
¶Deprecated since version 1.2.
SMTPConnection
クラスは汎用のメールバックエンドAPIが採用されたので廃止されま
した。
後方互換性のために SMTPConnection
は依然使えます。
django.core.mail
に SMTP バックエンド の
別名として存在します。これから書くコードには
get_connection()
を使うべきです。
Oct 26, 2017