概要
お問い合わせフォーム機能を作成してメールを送信する方法についてまとめた。
尚、Gmailを使用してメールを送信している。
前提
Googleアカウントのアプリパスワードを生成していること。
※アプリパスワードがないとGmailで送信できない
お問い合わせ機能
お問い合わせ機能について、全体の概要と実装方法を紹介する。
画面遷移
お問い合わせ機能は以下のように画面遷移する。
※ブログサイトにお問い合わせ機能を導入する例
実装全体像
お問い合わせビューの処理の流れは以下になる。
※FormViewを継承して作成
全体の流れ
GETまたはPOSTリクエストを受け取ると、dispatch()メソッドによってget()またはpost()メソッドが呼ばれる。
GETリクエスト
お問い合わせ画面表示処理。
空のお問い合わせフォームインスタンスを作成して画面に渡す。
POSTリクエスト
お問い合わせ送信処理。
画面からお問い合わせ情報の入力値を取得して入力チェックする。
入力チェックエラーが有る場合、エラー情報を保持したフォームインスタンスを画面に渡す。
入力チェックエラーが無い場合、メール送信処理を行ってリダイレクトする。
お問い合わせ機能まわりの実装
サーバー側と画面側について、実装内容を説明する。
サーバー側
サーバー側はビュー、フォーム、設定ファイルを実装する。
ビュー
お問い合わせビュー処理
from django.views.generic import FormView
from django.urls import reverse_lazy
from . import forms
from django.contrib import messages
from django.core.mail import EmailMessage
class ContactView(FormView):
"""お問い合わせ"""
# テンプレート
template_name = "contact.html"
# フォーム
form_class = forms.ContactForm
# お問い合わせ送信成功後URL
success_url = reverse_lazy("blogapps:contact")
def form_valid(self, form):
"""お問い合わせ送信処理"""
# パラメータ取得
name = form.cleaned_data["name"]
email = form.cleaned_data["email"]
title = form.cleaned_data["title"]
message_param = form.cleaned_data["message"]
# お問い合わせメールの送信処理(例として、自分自身にメールを送る設定)
subject = f"お問い合わせ: {title}"
message = f"名前: {name}\nメールアドレス: {email}\n\n{message_param}"
from_email = "XXXXXX@example.com" # 送信元のメールアドレス
recipient_list = ["XXXXX@gmail.com"] # 受信者のメールアドレスリスト
msg = EmailMessage(
subject=subject, body=message, from_email=from_email, to=recipient_list
)
try:
msg.send()
messages.success(self.request, "送信完了しました。")
except Exception as e:
messages.error(self.request, f"送信に失敗しました。エラー:{e}")
return super().form_valid(form)
GETリクエストによるお問い合わせ画面表示処理の場合、ContactFormインスタンスを生成して”contact.html”と組み合わせてレスポンスを返却する。
POSTリクエストによるお問い合わせ送信処理の場合、ContactFormインスタンスから画面入力値を取得してメール送信する。
name = form.cleaned_data["name"]
email = form.cleaned_data["email"]
title = form.cleaned_data["title"]
message_param = form.cleaned_data["message"]
バリデーション後のフォーム内画面入力値は、上記の記述で取得できる。
django.core.mail.EmailMessage
メール送信処理には、Djangoにもともと用意されているEmailMessageクラスを使用する。
インスタンスを作成する際に、以下のオプションを設定できる。
オプション | 内容 |
---|---|
subject | メールの件名 |
body | メールの本文 |
from_email | メールの送信元アドレス |
to | メールの送信先アドレス。リストまたはタプルで指定可能 |
bcc | bcc機能。リストまたはタプルで指定可能 |
cc | cc機能。リストまたはタプルで指定可能 |
attachments | 添付する添付ファイルのリスト |
headers | メッセージに追加する追加ヘッダー。キーはヘッダー名、値はヘッダー値 |
reply_to | メール送信時にReply-Toヘッダーで使用される受信者アドレスのリストまたはタプル |
インスタンスを作成する際にオプションをつけることで、メッセージ内容や送信先メールアドレス等を保持したオブジェクトを作成できる。
msg.send()
EmailMessageインスタンスのsend()メソッドを呼び出すことでメール送信ができる。
フォーム
お問い合わせフォーム
from django import forms
class ContactForm(forms.Form):
"""お問い合わせフォーム"""
# フィールド
name = forms.CharField()
email = forms.EmailField()
title = forms.CharField()
message = forms.CharField()
画面に表示させるフォーム部品を設定する。
設定ファイル
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
上記を設定することで、ターミナル上にメール送信内容を表示することができる。
テスト送信になるため、実際にメール送信はされない。
実際にメール送信する際には以下の設定を行う必要がある。
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = "smtp.gmail.com" # GmailのSMTPサーバー
EMAIL_PORT = 587 # Gmailサーバーのポート
EMAIL_HOST_USER = "XXXXX@gmail.com" # 自身のGmailアドレス(メール送信用SMTPサーバーの認証)
EMAIL_HOST_PASSWORD = "XXXXXX" # アプリパスワード
EMAIL_USE_TLS = True # SMTPサーバーと通信する際に、TLS(セキュア)接続する
上記を設定することで、実際にメール送信ができる。
自身のGmailと作成したアプリパスワード(セキュリティページから作成可能)を設定することで、Gmail経由でメール送信することができるようになる。
画面側
お問い合わせ画面は以下のように実装する。
お問い合わせ画面
<main class="mb-4">
<div class="container px-4 px-lg-5">
<div class="row gx-4 gx-lg-5 justify-content-center">
<div class="col-md-10 col-lg-8 col-xl-7">
<p>当ブログへのご意見、ご質問、ご相談等ありましたらお気軽に下記のフォームからお問い合わせください。<br/>また、コンテンツ等に問題がありましたらご報告ください。<br/><br/>必要事項を入力の上、【送信】ボタンをクリックしてください。</p>
<!-- メッセージ出力領域 -->
{% if messages %}
<ul class="list-unstyled">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="my-5">
<!-- * * * * * * * * * * * * * * *-->
<!-- * * お問い合わせフォーム * *-->
<!-- * * * * * * * * * * * * * * *-->
<form method="post">
{% csrf_token %}
<div class="form-floating">
<input class="form-control" id="name" type="text" name="name" placeholder="お名前を入力してください"/>
<label for="name">お名前</label>
{% if form.name.errors %}
<div class="text-danger">{{ form.name.errors.as_text }}</div>
{% endif %}
</div>
<div class="form-floating">
<input class="form-control" id="email" type="email" name="email" placeholder="メールアドレスを入力してください" />
<label for="email">メールアドレス</label>
{% if form.email.errors %}
<div class="text-danger">{{ form.email.errors.as_text }}</div>
{% endif %}
</div>
<div class="form-floating">
<input class="form-control" id="title" type="text" name="title" placeholder="件名を入力してください"/>
<label for="title">件名</label>
{% if form.title.errors %}
<div class="text-danger">{{ form.title.errors.as_text }}</div>
{% endif %}
</div>
<div class="form-floating">
<textarea class="form-control" id="message" name="message" placeholder="メッセージを入力してください"></textarea>
<label for="message">メッセージ</label>
{% if form.message.errors %}
<div class="text-danger">{{ form.message.errors.as_text }}</div>
{% endif %}
</div>
<br />
<!-- 送信ボタン-->
<button class="btn btn-primary" id="" type="submit">送信</button>
</form>
</div>
</div>
</div>
</div>
</main>
お問い合わせフォームのname、email、title、messageに合わせて画面を作成する。
メール送信に失敗したとき
VSCodeを使用していると、たまに以下のようなエラーが発生する。
対応
DNSサーバーをGoogleのDNSサーバーに変更することで解決した。
ターミナル
sudo vi /etc/resolv.conf
resolv.conf
nameserver 8.8.8.8