Djangoでお問い合わせフォームをお手軽に実装する
2017/02/13 12:30
  • フリーランスで活動していて、自身のWebサイトが仕事の受け口になっているような方も多いと思います。
    フォームをスクラッチで書くとなると結構大変ですが、Djangoなら強力なFormViewがあるので非常に簡単
    に実装することができます。

    直近でDjangoプロジェクトでお問い合わせフォームを作る機会がありましたので、
    DjangoのFormViewを使ったお手軽フォーム実装の記録をまとめます。

    前提っぽいこと

    既にDjangoのプロジェクトを運用済みで、かつgmailを利用していること。
    GmailのSMTPを使えるっていうのが便利ですね。
    将来的には「さくらのメールボックス」に移行するつもりではありますが、取り急ぎはこれで。

    Django: ver. 1.8
    SMTP: GmailのSMTPサーバを利用

    想定されるフォーム

    問い合わせ者の名前と、問い合わせ内容だけの簡易フォームを作成します。


    forms.py

    以下の内容でforms.pyを新規で作成します。

    from django import forms
    from django.core.mail import send_mail
    from django.conf import settings
    
    
    class ContactForm(forms.Form):
        name = forms.CharField() # 名前
        message = forms.CharField(widget=forms.Textarea) #問い合わせ内容
    
        # メール送信処理
        def send_email(self):
            # send email using the self.cleaned_data dictionary
            subject = self.cleaned_data['name']
            message = self.cleaned_data['message']
            from_email = settings.EMAIL_HOST_USER
            to = [settings.EMAIL_HOST_USER]
    
            send_mail(subject, message, from_email, to)
    

    ここはもう、models.pyでモデルを定義するような感覚で書いていきます。
    違いはそれほどないので、特に悩むことなく定義できると思います。

    まぁ、大部分は公式ドキュメントに記載のとおりですね。苦笑
    実はこれちょっと罠があって、send_email(self) の内容をきちんと定義してあげないとメールを送信できません。


    # send email using the self.cleaned_data dictionary

    上記のコメントのとおりなのですが、フォームから送信(POST)したデータは、ContactForm Contact.Formcleaned_data に格納されます。
    なので、その情報をもとにメール送信する処理を自分で書いてあげる必要があります。
    それが def send_mail(self): 内の情報となります。
    ぼくはここでちょっとハマりました。^^;

    views.py

    続いてviews.pyです。

    ...
    from django.views.generic.edit import FormView
    from .forms import ContactForm
    ...
    
    class ContactView(FormView):
        template_name = 'contact/index.jade'
        form_class = ContactForm
        success_url = '/contact/'
    
        def form_valid(self, form):
            # This method is called when valid form data has been POSTed.
            # It should return an HttpResponse.
            form.send_email()
            return super(ContactView, self).form_valid(form)
    

    Djangoのgeneric viewを使ってシンプルに実装しています。
    ここもそんなに迷うことはないと思います。

    form_valid の中で、先程定義した form.send_email() を実行しています。

    template/contact/index.jade

    Jade使いなのでJadeで紹介…汗

    form(action='', method='post')
        input(type='hidden', name='csrfmiddlewaretoken', value='#{csrf_token}')
        #{form.as_p}
        input(type='submit', value='Send message')
    

    フォームの出力がまさかの #{form.as_p} で一撃です。すごいですね。いやぁ、マジですごい。csrf_token は、デフォルトのテンプレートだったら {% csrf_token %} でOKです。
    また、#{form}, #{form.as_ul}, #{form.as_table}があり、好きな形式で
    フォームを生成してくれます。

    参考→ Form rendering options


    メール設定

    以下しれっと書いていますが、settings.pyに設定してあげれば良いようです。
    from_email = settings.EMAIL_HOST_USER
        to = [settings.EMAIL_HOST_USER]
    

    settings.py
    # Gメールで送信する例
    EMAIL_HOST = 'smtp.gmail.com'
    EMAIL_PORT = 587
    EMAIL_HOST_USER = 'hogehoge@gmail.com'
    EMAIL_HOST_PASSWORD = '2段階認証プロセス設定後に発行したアプリパスワード'
    EMAIL_USE_TLS = True
    

    2段階認証設定後に発行したアプリパスワードを利用しなかった場合、
    Net::SMTPAuthenticationError が返ってきます。
    設定方法等は以下の参考サイトに詳しく書かれていますのでそちらからどうぞ。

    参考サイト様


    Djangoで、ユーザ登録~URLクリックで仮登録、パスワードリマインダー等
    Gmail を使って Net::SMTPAuthenticationError が出力される場合の解決法

    長くなりましたが、以上です。

    続編も書きました。あわせてどうぞ!
    Djangoのお問い合わせフォームをいい感じにカスタマイズする


    人気ブログランキングへ ブログランキング・にほんブログ村へ
    ↑応援よろしくお願いします!m(_ _)m

  • <2017/02/03 15:46>
  • Python
  • DjangopythonmailformFormViewお問い合わせフォーム
  • 新しい記事へ
    Djangoのお問い合わせフォームをいい感じにカスタマイズする

    古い記事へ
    ブログランキングで最新記事を取得できるようにした時の話(1)

profile picture

自己紹介的な何か

@wkmettyでついったーやってます。時々。 6年間勤めたゲーム会社を2018年2月に退職しフリーランスのプログラマに。 WordPress Core, WP-CLI コントリビューター。 お仕事募集中です。