Djangoのユーザ管理アプリ作成の目次ページはこちらです。
今回は、フォーム機能を使ってDBへ新規登録をさせます。
UdemyのDjangoの基礎をマスターして、3つのアプリを作ろう!を参考に勉強していています。
また、フォームを扱っていくのでHTMLの基本的な知識がある方でないとも難しいかもしれません。
フォームとは
Djangoにはフォームクラスが存在します。
フォームクラスを定義して、入力フォームをHTMLのテンプレートへ渡すことができます。
そうすることで、入力フォームがHTML上で表示できます。
また、フォームで入力された内容を元にDBへ登録させることもできます。
フォームを使った処理の流れ
まず、フォームを使った表示、データ更新の流れを整理しておきます。
これから作っていく内容を流れとして理解しておきましょう。
①入力フォームをリクエストから呼び出す
②入力フォームをブラウザに表させる
③フォームに入力したデータをサーバに渡して登録
④登録した結果をブラウザに表示
この順番で処理を作成していきます。
①入力フォームをリクエストから呼び出す(urls.py)
まず最初に「~users/create」と言うURLを新規ユーザー登録のURLにします。
そのために、URLへアクセスされたときの動作をアプリのurls.pyに記入します。
1 2 3 4 5 6 7 8 9 10 11 12 |
from django.urls import path from . import views urlpatterns = [ path('', views.showUsers, name='showUsers'), #ユーザの詳細情報を表示する処理を呼び出す path('<int:id>', views.showDetail, name='showDetail'), #ユーザの登録フォームを呼び出す path('create', views.showCreateUserForm, name='showCreateUserForm'), ] |
11行目に追記をしました。
※この次にviews.pyの説明を記載します。
一旦viewsのことは置いておいて、やっていることだけ理解してみて下さい。
path(‘create’, views.showCreateUserForm, name=’showCreateUserForm’),の解説です。
‘create’:URLがusers/create場合の指定した処理を呼ぶという意味
views.showCreateUserForm:指定した処理が何かというと、views.pyのcreateUserです。
name=’showCreateUserForm’:リンク先に指定するときの名前で後で使います。
②入力フォームをブラウザに表させる
ここをもう少しかみ砕くと、以下の流れになります。
①htmlへフォームを渡す
②ブラウザにフォームを表示させる
ただし、フォームを定義していないので、先に作成するします。
modelからフォーム作成(forms.py)
「C:\django\myproject\myapp」の下にforms.pyを作成します。
そして、以下のように記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from django import forms from . models import UserInfo class UserForm(forms.ModelForm): class Meta: model = UserInfo fields = ('userName', 'country','sex','address','selfIntroduction') labels={ 'userName':'名前', 'country':'出身国', 'address':'住所', 'sex':'性別', 'selfIntroduction':'自己紹介', } |
やっていることは、model(DBの定義情報)を使って、フォームを定義しています。
ModelFormを継承したクラスの場合、データベースアクセスに関連する情報を入れることができます。
こういう書き方ができるのねと理解しておいてください。
5行目:class Meta:以降にフォームの情報を定義する
6行目:modelはUserInfoクラスを使うようにしています
7行目:フォームで使う列は5つということです。
8行目:ラベル属性を各列に対して指定しています。
ラベルを指定しないと、HTMLに表示したときに、英語の列名がそのまま表示されます。
こうすることで、入力欄のラベルが日本語になります。
ブラウザにフォームを表示させる(views.py)
views.py側で呼び出されるcreateUserメソッドを作成していきます。
内容は以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from .forms import UserForm #~~~~~~~~~~~~~~~~~ # 新規登録フォームHTMLへ返す def showCreateUserForm(request): #フォームを変数にセット form = UserForm() context = { 'userForm':form, } #detail.htmlへデータを渡す return render(request, 'myapp/create.html',context) |
UserFormをimportしています。
8行目でform変数にUserFormのインスタンスを格納しています。
10行目でcontext辞書に格納
15行目でcreate.htmlへcontextを渡しています。
フォームを表示するHTML作成(create.html)
create.htmlはまだ作っていないので、以下に作成します。
C:\django\myproject\myapp\templates\myapp
htmlの中身は以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{% extends './base.html' %} {% block app %} <h1>ユーザ登録</h1> <form action='{% url "showUsers" %}' method='post' class='form'> <!-- ユーザー登録フォームを表示 --> {% csrf_token %} {{ userForm }} <button type='submit' class='btn btn-outline-primary'>登録</button> <a href='{% url "showUsers" %}' class='btn btn-outline-secondary'>戻る</a> </form> {% endblock %} |
9行目でフォームの中に格納したform情報を表示させています。
8行目の{% csrf_token %}はリクエストが正常なものかをチェックしてくれるもので、今のところはおまじない的な理解で良いと思います。
6行目で登録ボタンクリックを受取るとshowUsers呼び出して、ユーザ一覧へ遷移する
※ユーザを登録する処理はこの次に書きます。
今はエラー回避のためにユーザ一覧へ遷移するようにしています。
表示させてみると、なんかレイアウトがぐちゃぐちゃ…
DjangoでフォームにBootstrapを適用するには、普通のHTMLのようにはできません。
なので、端末にダウンロードしたBootstrapを適用させます。
何やら頑張れば適用もできるようですが、私はこちらの方法は使いませんでした。
ダウンロードしたBootstrapをformに適用
まずはコマンドプロンプトでBootstrapを端末にインストールします。
1 |
pip install django-bootstrap4 |
次に、settings.pyからBootstrap4を認識させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', #追記 'myapp.apps.MyappConfig', # django-bootstrap4 'bootstrap4', ] |
12行目で追加をしています。
これで準備ができたので、先ほどのcreate.html上でBootstrapを適用させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{% extends './base.html' %} {% load bootstrap4 %} {% block app %} <h1>ユーザ登録</h1> <form action='{% url "showUsers" %}' method='post' class='form'> <!-- ユーザー登録フォームを表示 --> {% csrf_token %} {% bootstrap_form userForm %} <button type='submit' class='btn btn-outline-primary'>登録</button> <a href='{% url "showCreateUserForm" %}' class='btn btn-outline-secondary'>戻る</a> </form> {% endblock %} |
2行目でBootstrapを読み込んでいます。
10行目でフォームに対してBootstrapを適用させています。
表示結果はこうんな感じになりました。
③フォームに入力したデータをサーバに渡して登録、その後表示
現状は登録ボタンクリック時にユーザ一覧を表示していますが、ユーザ一を登録する処理を呼ぶようにします。
まずは登録ボタンをクリックした後、DBに登録する処理を作っていきます。
登録処理を呼び出す(urls.py)
まずはurls.pyにユーザ追加の処理を呼ぶように記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from django.urls import path from . import views urlpatterns = [ path('', views.showUsers, name='showUsers'), #ユーザの詳細情報を表示する処理を呼び出す path('<int:id>', views.showDetail, name='showDetail'), #ユーザの登録フォームを呼び出す path('create', views.showCreateUserForm, name='showCreateUserForm'), #ユーザ登録する処理を呼び出す path('add', views.addUser, name='addUser'), ] |
12行目でviewsのaddUserを呼ぶように記載しています。
addUserの処理は次で作成します。
ユーザをDBに追加する処理を作成(views.py)
処理の流れとしては、以下になります。
①フォームデータをDBに登録
②ユーザ一覧画面を表示
以下の処理を追加して①②両方ともviews.pyに記載しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#~~~~~~~~~~~~~~~~~ # フォームから受取ったデータをDBに登録する def addUser(request): #リクエストがPOSTの場合 if request.method == 'POST': #リクエストをもとにフォームをインスタンス化 userForm = UserForm(request.POST) if userForm.is_valid(): userForm.save() #登録後、全件データを抽出 userinfo = UserInfo.objects.all() context = { 'msg': '現在の利用状況', 'userinfo': userinfo, 'count':userinfo.count, #user.htmlへデータを渡す return render(request, 'myapp/users.html',context) |
4~9行目でPOSTのリクエストであれば、登録するという処理をしています。
11~19行目はユーザ一覧と同じ処理で、ユーザを全件取得して表示させています。
登録ボタンクリック後にaddUserを呼ぶ(create.html)
これでユーザ登録する処理が作成できました。
最後に、create.htmlの登録ボタンクリックした後の処理を書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{% extends './base.html' %} {% load bootstrap4 %} {% block app %} <h1>ユーザ登録</h1> <form action='{% url "addUser" %}' method='post' class='form'> <!-- ユーザー登録フォームを表示 --> {% csrf_token %} {% bootstrap_form userForm %} <button type='submit' class='btn btn-outline-primary'>登録</button> <a href='{% url "showCreateUserForm" %}' class='btn btn-outline-secondary'>戻る</a> </form> {% endblock %} |
7行目をshowUsers→addUserに書き換えました。
http://localhost:8000/users/createにアクセスして、
ユーザ情報を入力して試しに登録をしてみると。
上手く登録されて、一番下に「たくや」が追加されました!
一応詳細ページも見てみましたが、問題なしでした!
ユーザ追加ボタンをユーザ一覧に作成(users.html)
これで完了!かと思いました。
ただ、このままだとユーザ登録画面に行くことができません。
なのでユーザ一覧画面に、追加ボタンを作っておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
{% extends './base.html' %} {% block app %} <h1>ようこそ!</h1> <!-- テーブル --> <table class="table table-striped table table-bordered "> <thead> <tr> <th colspan="2">{{msg}}:{{count}}名</th> </tr> </thead> <tbody align="center"> <!-- count件(行)数分をループ --> {% for user in userinfo %} <tr> <!-- 4列分ユーザ情報を出力 --> <td>{{user.userName}}</td> <td><a href="{% url 'showDetail' user.id %}" class="btn btn-outline-primary">詳細</a> </td> </tr> {% endfor %} </tbody> </table> <a href="{% url 'showCreateUserForm' %}" class='btn btn-outline-primary'>ユーザ追加</a> {% endblock %} |
23行目にユーザ登録フォームをへ遷移するボタンを追加しました。
これでテーブル下にボタンが追加されました。
今回はこれで完了です。