メールの送信
Pythonはsmtplib
モジュールを介してメール送信インターフェースを提供しますが、Djangoはその上にいくつかの軽いラッパーを提供します。 これらのラッパーは、電子メールの送信をさらに高速にし、開発中の電子メール送信のテストを支援し、SMTPを使用できないプラットフォームのサポートを提供するために提供されています。
コードはdjango.core.mail
モジュールにあります。
簡単な例
2行で:
from django.core.mail import send_mail
send_mail(
'Subject here',
'Here is the message.',
'[email protected]',
['[email protected]'],
fail_silently=False,
)
メールは、:setting: `EMAIL_HOST` および:setting:` EMAIL_PORT` の設定で指定されたSMTPホストとポートを使用して送信されます。 :setting: `EMAIL_HOST_USER` および:setting:` EMAIL_HOST_PASSWORD` 設定が設定されている場合は、SMTPサーバーへの認証に使用され、:setting: `EMAIL_USE_TLS `および:setting:` EMAIL_USE_SSL` 設定は、安全な接続を使用するかどうかを制御します。
send_mail()
- send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)
ほとんどの場合、django.core.mail.send_mail()
を使用してメールを送信できます。
subject
、message
、from_email
、およびrecipient_list
パラメーターが必要です。
subject
:文字列。message
:文字列。from_email
:文字列。None
の場合、Djangoは:setting: `DEFAULT_FROM_EMAIL` 設定の値を使用します。recipient_list
:文字列のリスト。それぞれがメールアドレスです。recipient_list
の各メンバーは、電子メールメッセージの「宛先:」フィールドに他の受信者を表示します。fail_silently
:ブール値。False
の場合、エラーが発生するとsend_mail()
はsmtplib.SMTPException
を発生させます。 考えられる例外のリストについては、smtplib
のドキュメントを参照してください。これらはすべて、SMTPException
のサブクラスです。auth_user
:SMTPサーバーへの認証に使用するオプションのユーザー名。 これが提供されていない場合、Djangoは:setting: `EMAIL_HOST_USER` 設定の値を使用します。auth_password
:SMTPサーバーへの認証に使用するオプションのパスワード。 これが提供されていない場合、Djangoは:setting: `EMAIL_HOST_PASSWORD` 設定の値を使用します。connection
:メールの送信に使用するオプションのメールバックエンド。 指定しない場合、デフォルトのバックエンドのインスタンスが使用されます。 詳細については、 Eメールバックエンドのドキュメントを参照してください。html_message
:html_message
が指定されている場合、結果の電子メールは、テキスト/プレーンとして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
は、各要素が次の形式のタプルです。
(subject, message, from_email, recipient_list)
fail_silently
、auth_user
、auth_password
は、 send_mail()と同じ機能を持っています。
datatuple
の各要素は、個別の電子メールメッセージになります。 send_mail()と同様に、同じrecipient_list
の受信者はすべて、電子メールメッセージの「宛先:」フィールドに他のアドレスが表示されます。
たとえば、次のコードは、2つの異なるメッセージを2つの異なる受信者セットに送信します。 ただし、メールサーバーへの接続は1つだけ開かれます。
message1 = ('Subject here', 'Here is the message', '[email protected]', ['[email protected]', '[email protected]'])
message2 = ('Another Subject', 'Here is another message', '[email protected]', ['[email protected]'])
send_mass_mail((message1, message2), fail_silently=False)
戻り値は、正常に配信されたメッセージの数になります。
send_mass_mail()対。 send_mail()
send_mass_mail()と send_mail()の主な違いは、 send_mail()は実行されるたびにメールサーバーへの接続を開き、はメールサーバーへの接続を開くことです。 send_mass_mail()は、すべてのメッセージに単一の接続を使用します。 これにより、 send_mass_mail()の効率が少し向上します。
mail_admins()
- mail_admins(subject, message, fail_silently=False, connection=None, html_message=None)
django.core.mail.mail_admins()
は、:setting: `ADMINS` 設定で定義されているように、サイト管理者に電子メールを送信するためのショートカットです。
mail_admins()
は、件名の前に:setting: `EMAIL_SUBJECT_PREFIX` 設定の値を付けます。これは、デフォルトでは"[Django] "
です。
電子メールの「From:」ヘッダーは、:setting: `SERVER_EMAIL` 設定の値になります。
このメソッドは、利便性と読みやすさのために存在します。
html_message
が指定されている場合、結果の電子メールは、テキスト/プレーンコンテンツタイプとしてmessage
およびhtml_message
。
mail_managers()
- mail_managers(subject, message, fail_silently=False, connection=None, html_message=None)
django.core.mail.mail_managers()
はmail_admins()
と同じですが、:setting: `MANAGERS` 設定で定義されているように、サイト管理者にメールを送信する点が異なります。
例
これにより、 [email protected] と [email protected] に1通のメールが送信され、どちらも「宛先:」に表示されます。
send_mail(
'Subject',
'Message.',
'[email protected]',
['[email protected]', '[email protected]'],
)
これにより、 [email protected] と [email protected] にメッセージが送信され、両方に個別の電子メールが送信されます。
datatuple = (
('Subject', 'Message.', '[email protected]', ['[email protected]']),
('Subject', 'Message.', '[email protected]', ['[email protected]']),
)
send_mass_mail(datatuple)
ヘッダーインジェクションの防止
ヘッダーインジェクションは、攻撃者が追加の電子メールヘッダーを挿入して、スクリプトが生成する電子メールメッセージの「To:」と「From:」を制御するセキュリティエクスプロイトです。
上記で概説したDjango電子メール関数は、ヘッダー値の改行を禁止することにより、ヘッダーインジェクションから保護します。 subject
、from_email
、またはrecipient_list
のいずれかに改行(Unix、Windows、またはMacスタイル)が含まれている場合、電子メール機能(例: send_mail())はdjango.core.mail.BadHeaderError
(ValueError
のサブクラス)を発生させるため、電子メールを送信しません。 電子メール機能に渡す前に、すべてのデータを検証するのはあなたの責任です。
message
の文字列の先頭にヘッダーが含まれている場合、ヘッダーは電子メールメッセージの最初のビットとして出力されます。
これは、リクエストのPOSTデータからsubject
、message
、from_email
を取得し、それを [email protected] に送信して、にリダイレクトするビューの例です。完了したら「/ 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, ['[email protected]'])
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 は、電子メールメッセージ自体の作成を担当します。 次に、電子メールバックエンドが電子メールの送信を担当します。
便宜上、 EmailMessage は、単一の電子メールを送信するためのsend()
メソッドを提供します。 複数のメッセージを送信する必要がある場合は、メールバックエンドAPI が代替を提供します。
EmailMessageオブジェクト
- class EmailMessage
EmailMessage クラスは、次のパラメーターで初期化されます(位置引数が使用されている場合は、指定された順序で)。 すべてのパラメーターはオプションであり、send()
メソッドを呼び出す前であればいつでも設定できます。
subject
:メールの件名。body
:本文テキスト。 これはプレーンテキストメッセージである必要があります。from_email
:送信者のアドレス。[email protected]
と"Fred" <[email protected]>
の両方の形式が有効です。 省略した場合、:setting: `DEFAULT_FROM_EMAIL` 設定が使用されます。to
:受信者アドレスのリストまたはタプル。bcc
:電子メールの送信時に「Bcc」ヘッダーで使用されるアドレスのリストまたはタプル。connection
:メールバックエンドインスタンス。 複数のメッセージに同じ接続を使用する場合は、このパラメーターを使用します。 省略した場合、send()
が呼び出されたときに新しい接続が作成されます。attachments
:メッセージに添付する添付ファイルのリスト。 これらは、MIMEBase
インスタンスまたは(filename, content, mimetype)
トリプルのいずれかです。headers
:メッセージに追加する追加ヘッダーの辞書。 キーはヘッダー名、値はヘッダー値です。 ヘッダーの名前と値が電子メールメッセージに対して正しい形式であることを確認するのは、呼び出し元の責任です。 対応する属性はextra_headers
です。cc
:電子メールの送信時に「Cc」ヘッダーで使用される受信者アドレスのリストまたはタプル。reply_to
:電子メールの送信時に「Reply-To」ヘッダーで使用される受信者アドレスのリストまたはタプル。
例えば:
from django.core.mail import EmailMessage
email = EmailMessage(
'Hello',
'Body goes here',
'[email protected]',
['[email protected]', '[email protected]'],
['[email protected]'],
reply_to=['[email protected]'],
headers={'Message-ID': 'foo'},
)
このクラスには次のメソッドがあります。
send(fail_silently=False)
がメッセージを送信します。 電子メールの作成時に接続が指定された場合、その接続が使用されます。 それ以外の場合は、デフォルトのバックエンドのインスタンスがインスタンス化されて使用されます。 キーワード引数fail_silently
がTrue
の場合、メッセージの送信中に発生した例外は破棄されます。 受信者の空のリストは例外を発生させません。 メッセージが正常に送信された場合は1
を返し、それ以外の場合は0
を返します。message()
は、django.core.mail.SafeMIMEText
オブジェクト(PythonのMIMEText
クラスのサブクラス)または送信するメッセージを保持するdjango.core.mail.SafeMIMEMultipart
オブジェクトを作成します。 EmailMessage クラスを拡張する必要がある場合は、このメソッドをオーバーライドして、必要なコンテンツをMIMEオブジェクトに配置することをお勧めします。recipients()
は、to
、cc
、またはbcc
属性に記録されているかどうかに関係なく、メッセージのすべての受信者のリストを返します。 これは、サブクラス化時にオーバーライドする必要がある別の方法です。これは、メッセージの送信時にSMTPサーバーに受信者の完全なリストを通知する必要があるためです。 クラスで受信者を指定する別の方法を追加する場合は、このメソッドからも受信者を返す必要があります。attach()
は、新しい添付ファイルを作成してメッセージに追加します。attach()
を呼び出す方法は2つあります。MIMEBase
インスタンスである単一の引数を渡すことができます。 これは、結果のメッセージに直接挿入されます。または、
attach()
にfilename
、content
、mimetype
の3つの引数を渡すこともできます。filename
は電子メールに表示される添付ファイルの名前、content
は添付ファイル内に含まれるデータ、mimetype
はオプションのMIMEタイプです。アタッチメント。mimetype
を省略すると、MIMEコンテンツタイプは添付ファイルのファイル名から推測されます。例えば:
message.attach('design.png', img_data, 'image/png')
message / rfc822 の
mimetype
を指定すると、 django.core.mail.EmailMessage とemail.message.Message
も受け入れられます。text / で始まる
mimetype
の場合、コンテンツは文字列であることが期待されます。 バイナリデータはUTF-8を使用してデコードされ、それが失敗した場合、MIMEタイプは application / octet-stream に変更され、データは変更されずに添付されます。さらに、 message / rfc822 の添付ファイルは、 RFC 2046#section-5.2.1 に違反してbase64でエンコードされなくなり、表示に問題が発生する可能性があります。 Evolution および Thunderbird の添付ファイル。
attach_file()
は、ファイルシステムのファイルを使用して新しい添付ファイルを作成します。 添付するファイルのパスと、オプションで、添付に使用するMIMEタイプを使用して呼び出します。 MIMEタイプを省略すると、ファイル名から推測されます。 あなたはそれをこのように使うことができます:message.attach_file('/images/weather_map.png')
text / で始まるMIMEタイプの場合、バイナリデータは
attach()
のように処理されます。
代替コンテンツタイプの送信
電子メールにコンテンツの複数のバージョンを含めると便利な場合があります。 典型的な例は、メッセージのテキストバージョンとHTMLバージョンの両方を送信することです。 Djangoのメールライブラリでは、EmailMultiAlternatives
クラスを使用してこれを行うことができます。 EmailMessage のこのサブクラスには、電子メールにメッセージ本文の追加バージョンを含めるためのattach_alternative()
メソッドがあります。 他のすべてのメソッド(クラスの初期化を含む)は、 EmailMessage から直接継承されます。
テキストとHTMLの組み合わせを送信するには、次のように記述します。
from django.core.mail import EmailMultiAlternatives
subject, from_email, to = 'hello', '[email protected]', '[email protected]'
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)
は、 EmailMessage オブジェクトのリストを送信します。 接続が開いていない場合、この呼び出しは暗黙的に接続を開き、後で接続を閉じます。 接続がすでに開いている場合は、メールが送信された後も開いたままになります。
また、必要に応じて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(backend=None, fail_silently=False, *args, **kwargs)
デフォルトでは、get_connection()
を呼び出すと、:setting: `EMAIL_BACKEND` で指定されたメールバックエンドのインスタンスが返されます。 backend
引数を指定すると、そのバックエンドのインスタンスがインスタンス化されます。
fail_silently
引数は、バックエンドがエラーを処理する方法を制御します。 fail_silently
がTrueの場合、電子メール送信プロセス中の例外は黙って無視されます。
他のすべての引数は、電子メールバックエンドのコンストラクターに直接渡されます。
Djangoには、いくつかのメール送信バックエンドが付属しています。 SMTPバックエンド(デフォルト)を除いて、これらのバックエンドはテストおよび開発中にのみ役立ちます。 特別なメール送信要件がある場合は、独自のメールバックエンドを作成できます。
SMTPバックエンド
- class 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
の場合、各引数の値は一致する設定から取得されます。username
::setting: `EMAIL_HOST_USER`password
::setting: `EMAIL_HOST_PASSWORD`use_tls
::setting: `EMAIL_USE_TLS`use_ssl
::setting: `EMAIL_USE_SSL`timeout
::setting: `EMAIL_TIMEOUT`ssl_keyfile
::setting: `EMAIL_SSL_KEYFILE`ssl_certfile
::setting: `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'
このバックエンドは、本番環境での使用を目的としたものではありません。開発中に使用できる便利な機能として提供されています。
ファイルバックエンド
ファイルバックエンドは、電子メールをファイルに書き込みます。 このバックエンドで開かれる新しいセッションごとに、新しいファイルが作成されます。 ファイルが書き込まれるディレクトリは、:setting: `EMAIL_FILE_PATH` 設定から、または get_connection()で接続を作成するときにfile_path
キーワードから取得されます。 。
このバックエンドを指定するには、設定に次のように入力します。
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location
このバックエンドは、本番環境での使用を目的としたものではありません。開発中に使用できる便利な機能として提供されています。
バージョン3.1で変更: pathlib.Path
のサポートが追加されました。
インメモリバックエンド
'locmem'
バックエンドは、django.core.mail
モジュールの特別な属性にメッセージを格納します。 outbox
属性は、最初のメッセージが送信されたときに作成されます。 これは、送信される各メッセージの EmailMessage インスタンスのリストです。
このバックエンドを指定するには、設定に次のように入力します。
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
このバックエンドは、本番環境での使用を目的としたものではありません。開発およびテスト中に使用できる便利な機能として提供されています。
Djangoのテストランナーは、このバックエンドをテストに自動的に使用します。
ダミーバックエンド
名前が示すように、ダミーのバックエンドはメッセージに対して何もしません。 このバックエンドを指定するには、設定に次のように入力します。
EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
このバックエンドは、本番環境での使用を目的としたものではありません。開発中に使用できる便利な機能として提供されています。
カスタムメールバックエンドの定義
メールの送信方法を変更する必要がある場合は、独自のメールバックエンドを作成できます。 設定ファイルの:setting: `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 インスタンス(またはサブクラス)のリストを取得し、単一の接続を使用してそれらすべてを送信します。
たとえば、送信したい定期的な電子メールを表す 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',
'[email protected]',
['[email protected]'],
connection=connection,
)
email1.send() # Send the email
# Construct two more messages
email2 = mail.EmailMessage(
'Hello',
'Body goes here',
'[email protected]',
['[email protected]'],
)
email3 = mail.EmailMessage(
'Hello',
'Body goes here',
'[email protected]',
['[email protected]'],
)
# 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にメールをまったく送信させたくない場合があります。 たとえば、Webサイトの開発中に、何千もの電子メールを送信したくない場合がありますが、電子メールが適切な条件で適切な人に送信され、それらの電子メールに適切なコンテンツが含まれていることを検証する必要があります。 。
ローカル開発用に電子メールを構成する最も簡単な方法は、コンソール電子メールバックエンドを使用することです。 このバックエンドはすべての電子メールをstdoutにリダイレクトし、メールの内容を検査できるようにします。
file 電子メールバックエンドは、開発中にも役立ちます。このバックエンドは、すべてのSMTP接続の内容を、自由に検査できるファイルにダンプします。
もう1つのアプローチは、ローカルで電子メールを受信して端末に表示する「ダム」SMTPサーバーを使用することですが、実際には何も送信しません。 Pythonには、単一のコマンドでこれを実現するための組み込みの方法があります。
python -m smtpd -n -c DebuggingServer localhost:1025
このコマンドは、ローカルホストのポート1025でリッスンしている最小限のSMTPサーバーを起動します。 このサーバーは、すべての電子メールヘッダーと電子メール本文を標準出力に出力します。 次に、:setting: `EMAIL_HOST` と:setting:` EMAIL_PORT` を適宜設定するだけです。 SMTPサーバーオプションの詳細については、smtpd
モジュールのPythonドキュメントを参照してください。
アプリケーションでの電子メール送信の単体テストについては、テストドキュメントの電子メールサービスセクションを参照してください。