Django のクラスベース Generic view の FormView を使ったフォームを実装したいと思います。クラスベース Generic view は、関数ベース の view に比べ、コードが簡潔になりますので、おすすめです。FormView 以外にも便利な Generic view たくさんありますので、マニュアルに目を通して、一通り把握しておくことをお勧めします。
Built-in class-based generic views
Contents
完成イメージ
バージョン
- Python 3.6.4
- Django 2.0.3
インストール
Python, Django のインストール
Python と Django のインストールについては、こちらの記事を参考にしてください。
実装
forms.py
from django import forms class ContactForm(forms.Form): name = forms.CharField(label='名前', widget=forms.TextInput(attrs={'class': 'form-control'})) email = forms.EmailField(label='email', widget=forms.EmailInput(attrs={'class': 'form-control'})) message = forms.CharField(label='内容', widget=forms.Textarea(attrs={'class': 'form-control'})) def send_email(self): # send email using the self.cleaned_data dictionary pass
フォームを定義します。今回はお問い合わせフォームということで、name、email、message のフィールドを定義しています。
views.py
from django.views.generic import FormView from .forms import ContactForm class ContactView(FormView): form_class = ContactForm template_name = 'app/contact.html' success_url = '.' def form_valid(self, form): form.send_email() return super().form_valid(form)
フォームの定義を、form_class に設定します。
フォームの入力値に問題がなければ(バリデーションに通れば)form_valid 関数が実行されます。
これだけのコード量でフォームを実装できる Generic view、素晴らしいですね!
contact.html
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous"> <title>お問い合わせフォーム</title> </head> <body> <div class="container"> <h1>お問い合わせフォーム</h1> <form action="." method="post">{% csrf_token %} {{ form.as_p }} <input class="btn btn-primary" type="submit" value="送信" /> </form> </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script> </body> </html>
HTML は bootstrap の Starter template をベースにしています。
form.as_p で、views.py の form_class に設定したフォームの HTML を p タグで出力してくれます。他にも、ul タグ用の form.as_ul や table タグ用の form.as_table があります。
ファイル構成
$ tree . ├── app │ ├── __init__.py │ ├── apps.py │ ├── forms.py │ ├── templates │ │ └── app │ │ └── contact.html │ └── views.py ├── form_validation │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 4 directories, 10 files
最終的にこのようなファイル構成になりました。
実行
$ python3.6 manage.py runserver 0.0.0.0:8000
実行はいつものように runserver を使います。
http:// [IPアドレス] :8000 でアクセスしてフォームの確認ができると思います。
まとめ
簡単にですが、Django のフォームを実装して見ました。
Generic view を使うと、コードを簡潔にできることがわかったと思います。
このままでも、Django がある程度バリデーションしてくれますが、実際はもっと複雑なバリデーションが要求されると思います。
次回は、そのバリデーションについて、実装してみたいと思います。
メール送信について
今回実装したのは、お問い合わせフォームですが、メール送信部分については、実装していません。
機会があれば、説明したいと思いますが、すぐに知りたい人はこちらを参考にしてもらえればと思います。
settings.py にメール関連の設定をして、send_mail ライブラリでメールを送信することができます。