Djangoでメール送信を実装してみる


みなさん、こんにちは。S.Yです。
実際に現場でDjangoでのメール送信を実装する機会があったので実装方法についてまとめました。

前提条件

次の環境で動作させていきます。

  • Visual Studio Code version: 1.76.0
  • python version: 3.9.14
  • django version: 4.1.7

メール送信実装手順

メールサーバーの設定

settings.pyでメールの送信設定を追加します。
settings.py内の EMAIL_HOST と EMAIL_PORT で指定された SMTP ホストとポートを使用して、メールが送信されます。EMAIL_HOST_USER と EMAIL_HOST_PASSWORD が指定されている場合は、SMTP サーバーの認証に使われます。
settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtpサーバー'
EMAIL_HOST_USER = 'デフォルトのEmailアドレス'
EMAIL_HOST_PASSWORD = 'メールサーバーのパスワード'
EMAIL_PORT = '1025' #メールサーバーで指定されているポート
EMAIL_USE_TLS = False # 送信中の文章を暗号化
DEFAULT_FROM_EMAIL = '任意のメールアドレス'

開発環境でメールをコンソールに表示するには以下のように変更します。

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

メールの送信

send_mail()でメールを送信します。 引数は主に("題名", "本文", "送信元メールアドレス", "宛先メールアドレス")です。
from_emailがNoneの場合、DEFAULT_FROM_EMAIL の値を使用します。
fail_silentlyは入力必須ではありません。Falseの場合、送信エラーが発生した場合に smtplib.SMTPException を発生させます。
views.py

    """題名"""
    subject = "題名"
    """本文"""
    message = "本文"
    """送信元メールアドレス"""
    from_email = "system@example.com"
    """宛先メールアドレス"""
    recipient_list = [
        "to@example.com"
    ]
    
    send_mail(subject, message, from_email, recipient_list, fail_silently=False))

サンプルプログラム

以上のことを踏まえてコンソールにメールの送信内容を表示するプログラムを作成してみます。

Djangoプロジェクト作成

まずはプロジェクトを作成します。

django-admin startproject mysite
cd mysite
python manage.py startapp send_mail

プロジェクト構成

mysite
- mysite
  - __pycache__
  - __init__.py
  - settings.py
  - urls.py
  - wsgi.py
- send_mail 
  - __pycache__
  - migrations
  - templates  # 追加
     - index.html  # 追加
  - admin.py
  - apps.py
  - models.py
  - tests.py
  - urls.py  # 追加
  - views.py
- db.sqlite3
- manage.py

アプリケーションの編集

"INSTALLED_APPS"にsend_mail.apps.AppConfigを追加します。
メールの送信設定はsettings.pyの一番下に追加します。
mysite/mysite/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'send_mail.apps.SendMailConfig', #追加
]

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
DEFAULT_FROM_EMAIL = 'system@example.com'

templateを作成します。
mysite/send_mail/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>success</title>
</head>
<body>
	<h1>send mail complete!</h1>
</body>
</html>

view.pyを修正します。
メールを送信する関数を実装します。
mysite/send_mail/views.py

from django.shortcuts import render
from django.core.mail import send_mail

def index(request):
    """題名"""
    subject = "題名"
    """本文"""
    message = "本文"
    """送信元メールアドレス"""
    from_email = "system@example.com"
    """宛先メールアドレス"""
    recipient_list = [
        "to@example.com"
    ]
    send_mail(subject, message, from_email, recipient_list, fail_silently=False)
    return render(request, 'index.html')

先ほどview.pyで作成した関数のルーティングを設定します。
mysite/send_mail/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index),
]

mysite/mysite/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('send_mail.urls')), #"追加"
]

動作確認

サーバーを起動する

python manage.py runserver

html

無事に送信されたメールがコンソールに出力されました。
コンソール

デフォルトでは題名が文字化けしてしまいます。日本語で表示するには、EmailBackend を拡張することで対処できます。具体的な方法は以下の資料が詳しいのでご参照ください。

おわりに

send_mail()を使うことでメール送信を実装することができました。
お役に立てば幸いです。
最後までお読みいただきありがとうございます。

参考

https://docs.djangoproject.com/en/4.1/topics/email/