Django v1.0 documentation

電子メールの送信

revision-up-to:8961 (1.0)

Python の smtplib ライブラリ を使えば、比較的簡単に電子メールを送信でき ますが、 Django ではこのライブラリへの軽量ラッパを二つ用意して、電子メール の送信を極めて素早くおこなえるようにしています。

コードは: 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()

電子メールを送信する最も簡単な方法は django.core.mail.send_mail() 関数です。この関数の定義は以下の通りです:

send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None)

subject, message, from_email および recipient_list は必須の パラメタです。

  • subject: 文字列です。
  • message: 文字列です。
  • from_email: 文字列です。
  • recipient_list: 文字列からなるリストで、各々が電子メールアドレス を表します。 recipient_list に入っているユーザは、お互いに他のユー ザをメールの "To:" フィールドで見られます。
  • fail_silently: ブール型の値です。 False なら send_mailsmtplib.SMTPException 例外を出すようになります。 送出されうる例外のリストは smtplib のドキュメント を参照してくださ い。いずれの例外も SMTPException のサブクラスです。
  • auth_user: オプションです。 SMTP サーバでの認証に使うユーザ名です。 この値を指定しなければ、 Django は EMAIL_HOST_USER 設定を使います。
  • auth_password: オプションです。 SMTP サーバでの認証に使うパスワー ドです。この値を指定しなければ、 Django は EMAIL_HOST_PASSWORD 設 定を使います。

send_mass_mail()

django.core.mail.send_mass_mail() は一括電子メール (mass e-mail) の送信 用の関数です。この関数の定義は以下の通りです:

send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None)

datatuple はタプルで、各要素は以下の形式になっています:

(subject, message, from_email, recipient_list)

fail_silently, auth_user および auth_passwordsend_mail() と同じです。

datatuple の各要素ごとに個別の電子メールメッセージを作成して送信します。 send_mail() と同様、同じ recipient_list に入っている受信者は、他の 受信者を "To:" フィールドで見られます。

send_mass_mail() と send_mail()

send_mass_mail()send_mail() の大きな違いは、 send_mail() は実行の度にメールサーバに接続するのに対し、 send_mass_mail() は全ての メッセージの送信に一つの接続を使う点です。このため、 send_mass_mail() の方が少しだけ効率的です。

mail_admins()

django.core.mail.mail_admins()ADMINS に書かれたサイト管 理者への電子メール送信を行うためのショートカットです。関数の定義は以下の通 りです:

mail_admins(subject, message, fail_silently=False)

mail_admins() はサブジェクトの先頭に EMAIL_SUBJECT_PREFIX の 設定値を付加します。デフォルトは "[Django] " です。

電子メールの "From:" ヘッダには SERVER_EMAIL の設定値が入ります。

このメソッドは利便性と可読性のために用意されています。

mail_managers()

django.core.mail.mail_managers()mail_admins と同じですが、 電子メールを MANAGERS に書かれたサイトマネジャに送信します 関数は以下のように定義されています:

.. function:: mail_managers(subject, message, fail_silently=False)

以下の例は、単一の電子メールを john@example.comjane@example.com に送信 します。両方の宛先が "To:" に表示されます:

send_mail('Subject', 'Message.', 'from@example.com',
    ['john@example.com', 'jane@example.com'])

以下の例は、単一の電子メールを john@example.comjane@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.')

EmailMessage および SMTPConnection クラス

Django 1.0 で新たに登場しました.

Django の send_mail() および send_mass_mail() 関数は、実際には django.core.mailEmailMessage クラスや SMTPConnection クラス に対して薄いラッパをかぶせたものにすぎません。 Django からメールを送信する 方法をカスタマイズしたければ、これらのクラスをサブクラス化してやりたいこと を実現できます。

Note

send_mail() をはじめとしたラッパ関数から利用できる機能は、 EmailMessage クラスで提供している全ての機能をカバーしているわけでは ありません。BCC への宛先を指定やファイルの添付、マルチパート形式メール の送信を行いたい場合には、 EmailMessage インスタンスを直接生成する 必要があります。

send_mail() がこのようないささかややこしい仕様なのは、設計上の事情 によるものです。 send_mail() などの関数はもともと単なる Django 向け の単純なメールインタフェースでしかありませんでした。その後、 send_mail() に指定できるパラメタが少しづつふえてきたのです。今となっ ては、メールメッセージを扱うためのよりオブジェクト指向の設計に移行して、 send_mail() は互換性のためだけにおいておく方が有意義でしょう。

一般に、 EmailMessage はメールメッセージ自体の生成に関わります。 SMTPConnection はメール送信処理におけるネットワーク接続に関わっています。 このことは、同じ接続 (SMTPConnection インスタンス) を再利用すれば、複数 のメッセージを一括送信できることを示しています。

EmailMessage オブジェクト

EmailMessage クラスは以下のパラメタ (固定引数を使う場合には以下に示す順 番に指定します) で初期化します。パラメタは全て省略可能で、 send() メソッ ドを呼び出す前であればいつでも設定しなおせます。

  • subject: メールの題名です。
  • body: メール本文です。平文テキストのメッセージでなければなりませ ん。
  • from_email: 送信者のアドレスです。 fred@example.com 形式でも Fred <fred@example.com> 形式でもかまいません。省略すると、 DEFAULT_FROM_EMAIL の設定値を使います。
  • to: 受信者アドレスのリストまたはタプルです。
  • bcc: メールを送信する際に "Bcc" ヘッダに指定するアドレスのリスト またはタプルです。
  • connection: SMTPConnection のインスタンスです。一つの SMTP 接 続を使い回して複数のメッセージを送信したい場合に指定します。省略する と、 send() を呼び出す瞬間に新しい接続を生成します。
  • attachments: メールに添付するデータのリストです。リストの各要素は、 email.MIMEBase.MIMEBase のインスタンスか、 (filename, content, mimetype) からなるタプルです。
  • headers: メッセージに追加するヘッダの辞書です。ヘッダ名をキーに、 ヘッダ値を値にします。このパラメタを使うのなら、指定したヘッダがメー ルメッセージ中で正しいヘッダとして扱われるように気をつけねばなりませ ん。

例を示します:

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) メソッドを呼び出すと、 connection 属 性に指定した接続を使ってメッセージを送信します。接続がなければ、自動的 に新たな接続を生成して使います。 fail_silentlyTrue にすると、 メッセージ送信に失敗した場合に例外を送出します。

  • message()django.core.mail.SafeMIMEText クラス (Python の email.MIMEText.MIMEText クラスのサブクラス) または django.core.mail.SafeMIMEMultipart クラスのインスタンスを生成します。 このオブジェクトには送信するメッセージが入っています。 EmailMessage クラスを拡張する必要がある場合、おそらくこのメソッドを オーバライドして、所望の内容を MIME オブジェクト内に配置することになるで しょう。

  • recipients() はメッセージの全ての宛先からなるリストを返します。この 宛先リストは、 tobcc に指定した全ての宛先が入ります。 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()

デフォルトでは、 EmailMessagebody パラメタの MIME タイプは "text/plain" です。実践的には、このパラメタは変更せずにおいた方がよいで しょう。なぜなら、メールを受信した人が使っているメールクライアントソフトに 関係なくメッセージを読めるよう保証できるからです。とはいえ、メールの読み手 が拡張コンテンツ形式 (alternative content type) のメッセージを扱えると分かっ ている場合には、 EmailMessagecontent_subtype 属性を使って、主メッ セージのコンテンツタイプを変更できます。メールのメジャーコンテンツタイプは 常に "text" ですが、サブタイプは以下のように変更できます:

msg = EmailMessage(subject, html_content, from_email, [to])
msg.content_subtype = "html"  # Main content is now text/html
msg.send()

SMTPConnection オブジェクト

class SMTPConnection

SMTPConnection クラスの初期化は、SMTP サーバのホスト、ポート、SMTP 接続 を行うユーザ名、そしてパスワードを指定して初期化でき、それぞれのパラメタは host, port, username, password オプションで指定します。パラ メタを省略すると、設定ファイルから値を読み出します。

たくさんの数のメッセージを一度に送信したいなら、 SMTPConnection クラス の send_messages() メソッドが便利です。このクラスは EmailMessage ク ラス (またはサブクラス) のインスタンスのリストを引数にとり、一つの SMTP 接 続で一度に送信します。例えば、 get_notification_email() という関数があ り、この関数が定期的に送信されるメールの入った EmailMessage オブジェク トのリストを返すとしましょう。メッセージは以下のようにして一括送信できます:

connection = SMTPConnection()   # デフォルトの設定で接続を作成
messages = get_notification_email()
connection.send_messages(messages)