前回の記事でDjangoのmodels.pyの使い方について勉強しました。
前回の記事
今回はforms.pyとmodels.pyを活用して、フォームから送信されたデータをデータベースに登録する、ということをやってみたいと思います。
前提としてプロジェクトの作成やURLの設定等の事前準備は済ませているものとして進めていきます。
(事前準備は以下記事をご参照ください)
また今回はこちらの記事を参考にさせていただきました。
①モデルの定義
今回はフォームから送信された名前をデータベースに登録し、登録された名前をHTML上に順番に表示してみます。
from django.db import models class Hello(models.Model): your_name = models.CharField(max_length=10) def __str__(self): return "<{0}>".format(self.your_name)
まずクラスを定義し、データベースにHelloという名前でテーブルを作成します。
次にカラムの作成ですが、今回はDjangoの「CharField」というフィールドを使用します。
これは文字列の型を扱うフィールドで、引数の指定により最大文字数を10文字に制限しています。
モデルの定義が終わったらmigrateしておきます。
python manage.py makemigrations python manage.py migrate
②フォームの作成
次に名前情報を送信するようのフォームを作成します。
コードは以下のようになります。
from django import forms class HelloForm(forms.Form): your_name = forms.CharField( max_length = 20, required=True, widget=forms.TextInput() ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['your_name'].widget.attrs['class'] = 'form-control'
③Views.pyの作成
Views.pyは以下のようになります。
from django.shortcuts import render,redirect from .forms import HelloForm from .import models def hello_models(request): form = HelloForm(request.POST or None) if form.is_valid(): models.Hello.objects.create(**form.cleaned_data) return redirect('index') d = { 'form' : form, 'hello_qs': models.Hello.objects.all().order_by('-id'), } return render(request, 'myapp/index.html', d)
まず
form = HelloForm(request.POST or None)
の部分でHelloFormクラスのインスタンスを作成します。
次に
if form.is_valid(): models.Hello.objects.create(**form.cleaned_data) return redirect('index')
の部分でformの内容(送信されたデータの形式)が正しければDBに情報を追加する処理を行っています。
戻り値の部分は通常であれば render関数を使用してテンプレートファイルをレンダリングするのですが、今回は「redirect」関数を使用しています。
これは「PRGパターン」という処理を実装するためのものです。
通常POST処理(フォームからの情報の送信等)を行った際に、ブラウザをリロードすると再度同じ投稿が行われてしまう、という現象が起こります。
これを回避するために、POSTリクエストが正常に処理された場合にはそのままHTMLのレスポンスを返すのではなく、別のURLパターンにリダイレクトする、という処理を行う必要があります。
そのためこの後解説するアプリのurls.pyでは複数のURLパターンを設定しています。
ちなみにredirectの引数である「index」はurls.pyで「name=」で設定した値になります。
最後に
d = { 'form' : form, 'hello_qs': models.Hello.objects.all().order_by('-id'), } return render(request, 'myapp/index.html', d)
の部分でレンダリングの設定を行っています。
'hello_qs': models.Hello.objects.all().order_by('-id')
はHelloテーブルのすべてのレコードを取得し、id順に並び変えて"hello_qs"変数に格納しています。
④アプリのurls.pyの設定
from django.conf.urls import url from . import views urlpatterns = [ url(r'^/', views.hello_models, name='index'), url(r'^models/$', views.hello_models, name="hello_models"), ]
今回用意するテンプレートファイルはindex.html一種類ですが、前述の通りPRGパターンでの処理を行うためURLは2種類用意されています。
⑤テンプレートファイルの作成
{% block content %} <div class="container"> {{ message }} <h1>名前を登録する</h1> <h2>登録</h2> <form method="post" action=""> <div class="form-group"> {{ form.errors.your_name }} <label>{{ form.your_name.label }} {{ form.your_name }}</label><br> <input type="submit" class="btn btn-primary" value="送信"> {% csrf_token %} </div> </form> <hr> <h2>一覧</h2> {% for h in hello_qs %} {{ h.your_name }}<br> {% endfor %} </div> {% endblock %}
これでhttp://127.0.0.1:8000/myapp/modelsにアクセスすると正常に起動すると思います。
フォームから送信されたデータはデータベースに保存され、id順にhtmlに表示されていきます。