DjangoでToDoList開発Part4
こんにちは、にわこまです。
今回は、タイトル、内容、締切日を入力してToDoを追加することができるページを作成します。
「DjangoでToDoList開発」シリーズはDjangoのチュートリアルとして利用されることを目的としています。そのため、誤字脱字や分かりにくい点がございましたら、ご連絡お願い致します。
スポンサードサーチ
DjangoでToDoList開発Part4
今までは、Django Adminでタイトルなどを入力してきましたが、今回はブラウザから、タイトル、内容、締め切り日を入力して、ToDoを追加することができるようにします。
そのためには、入力フォームをまとめることができるフォーム(forms.py)の作成、ページレイアウト(todoAdd.html)の作成、入力前後の処理(views.py)の作成を行います。
フォームの作成
フォームとは、ユーザから入力を受ける部分のことを指します。
まず、そのフォームに必要なデータをひとまとめにするフォームクラスを作成します。 todolistの下にforms.pyというファイルを作成し、編集します。
from django import forms
from .models import MyToDoList
# your code...
# Add Form
class todoAddForm(forms.Form):
title = forms.CharField(label="Title", max_length=200)
contents = forms.CharField(label="Contents", widget=forms.Textarea)
deadline = forms.DateField(label="Deadline")
コードの解説
1行目の「from django import forms」は、フォームを作る上で必ず必要なものであり、フォーム用のフィールドを使う時に宣言します。
6行目~9行目は、ToDoを追加するときに必要なものを作成しています。追加するときに必要なものは、タイトル、内容、締切日の3つであるため3つの変数が用意されています。
7行目の「title」は、タイトルを入力するためのフォームです。モデルと同じくCharFielを指定し、max_lengthも指定します。
8行目の「contents」は、ToDoの内容を入力するためのフォームです。モデルとは異なり、TextFieldではなくCharFieldを指定します。さらに、widgetを「forms.Texarea」と指定します。
フォームのCharFieldは、デフォルトで「widget=forms.TextInput」となっています。つまり1行分しか入力できません。複数行入力できるようにしたい時は、「widget=forms.Textarea」とします。 またフォームでTextFieldを使わない理由は、単純にTextFieldがフォームで用意されていないからです。
9行目の「deadline」は、締切日を入力するためのものです。モデルと同じくDateFieldを指定します。
フォームでは、必ずlabelを指定するようにしましょう。
現在のフォルダ状況(todolistから)
todolist
|- admin.py
|- apps.py
|- forms.py # 追加部
|- migrations
|- models.py
|- static
|- templates
|- tests.py
|- urls.py
|- views.py
|- __init__.py
|- __pycache__
スポンサードサーチ
ToDo追加ページの作成
ToDoを追加するページの作成を行います。todolist/templates/todolist/にtodoAdd.htmlを作成し、編集します。
{% extends 'todolist/base.html' %}
{% block title %}ToDoAddForm{% endblock %}
{% block contents %}
<article class="todoadd">
<div class="page-name">
<h1>ToDo追加フォーム</h1>
</div>
<div class="todoadd-form">
<form action="{% url 'todoAdd' %}" method="post">
{% csrf_token %}
{% for field in form %}
<div class="field-row">
{{ field.label_tag }}{{ field }}
</div>
{% endfor %}
<input type="submit" value="Add">
</form>
</div>
</article>
{% endblock %}
コードの解説
1行目の「{% extends ‘todolist/base.html’ %}」は、base.htmlを拡張してtodoAdd.htmlを作成するという宣言です。
3行目の「{% block title %}ToDoAddForm{% endblock %}」は、タイトルブロックにToDoAddFormを代入しています。
5行目~22行目は、contentブロックに代入するコードです。
12行目の「{% csrf_token %}」は、アプリケーションの脆弱性を突く攻撃を防ぐためのものです。formを書くならば、必ず必要なものです。
csrfとは、クロスサイトリクエストフォージェリのことです。アプリケーションの脆弱性を突く攻撃方法のことです。
13行目~17行目は、forブロックです。繰り返し処理がされています。formからlabelとfieldが取り出されています。
最後に、11行目で指定したURL「todoAdd」は、後でurls.pyで指定するため覚えておきます。
現在のフォルダ状況(templates/todolistから)
templates
|- todolist
|- base.html
|- index.html
|- todoAdd.html # 追加部
views.pyの編集(入力前処理)
ToDoを入力する前の処理を作成します。todolist/views.pyを編集します。
from django.shortcuts import render
from django.http import HttpResponse
from .models import MyToDoList
from .forms import todoAddForm # 追加部
・
・
・
省略
・
・
・
# === ここから 追加 ===
def todoAdd(request):
form = todoAddForm
params = {
'form':form,
}
return render(request, 'todolist/todoAdd.html', params)
# === ここまで 追加 ===
以上でタイトル、内容、締切日を入力するための処理が完了です。
コードの解説
6行目の「form .forms import todoAddForm」は、forms.pyのtodoAddFormを使うための宣言です。
15行目~21行目は、具体的な処理について書かれています。
17行目の「form = todoAddForm」は、フォームをformという変数に代入しています。
18行目~20行目は、paramsの指定を行っています。
21行目は、renderによってtodoAdd.htmlにparamsを指定しています。これにより、todoAdd.html内でformが使えるようになります。
urls.pyの編集
viewを作成したためURLを設定します。todolist/urls.pyを編集します。
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('todoAdd', views.todoAdd, name='todoAdd'), # 追加部
]
今回追加したURLの名前は、todoAdd.htmlでformに設定したURLです。具体的には、pathの第3引数「name=””」にtodoAddを設定します。
動作確認
正しく動くか確認を行うため、サーバを起動します。
python manage.py runserver
サーバを起動させたら、「http://localhost:8000/todolist/todoAdd」にアクセスします。以下のように表示されます。
適当なテキストを入力してAddをクリックしてみます。次に、トップページにアクセスします。以下のように表示されます。
入力したテキストが追加されていません。viewで入力後の処理を書いていないためです。つまり、入力したデータを保存する処理がされていません。
スポンサードサーチ
views.pyの編集(入力後処理)
入力後の処理、つまり送られてきたデータを保存する処理を作成します。todolist/views.pyを編集します。
from django.shortcuts import render
from django.shortcuts import redirect # 追加部
from django.http import HttpResponse
・
・
・
省略
・
・
・
def todoAdd(request):
# === ここから 追加 ===
if(request.method == 'POST'):
mtdl = MyToDoList()
mtdl.title = request.POST['title']
mtdl.contents = request.POST['contents']
mtdl.deadline = request.POST['deadline']
mtdl.save()
return redirect(to='/todolist/')
# === ここまで 追加 ===
form = todoAddForm
params = {
'form':form,
}
return render(request, 'todolist/todoAdd.html', params)
コードの解説
2行目の「from django.shortcuts import redirect」は、リダイレクトするために必要なものです。保存後トップページに移動するときに使います。
13行目~19行目は、データがPOSTメソッドで送られてきた、つまりAddをクリックしたときの処理です。
13行目は、requestがPOSTメソッドかどうかを判定しています。
14行目の「mtdl = MyToDoList()」は、オブジェクトを作成しています。
15行目~17行目は、それぞれオブジェクトの対応する変数に送られてきたデータを代入しています。
18行目の「mtdl.save()」は、代入したデータを保存しています。
entryDateは、保存した日付が自動で保存されるため、ここでは代入しません。 また、doneはデフォルトがFalseになっているため、ここでは代入しません。
19行目は、redirect関数によってトップページにリダイレクトします。
動作確認
データ入力後にトップページへリダイレクトするか、またデータが正しく保存されるか確認するためサーバを起動します。
python manage.py runserver
サーバを起動させたら、「http://localhost:8000/todolist/todoAdd」にアクセスします。アクセスした後は、適当なデータを入力してAddをクリックします。
Addクリック後は、トップページに移動します。入力したデータが表示されているか確認します。表示されていれば動作確認は完了です。
表示されてない人は、リロードしてみてください。
まとめ
今回は、ToDoを追加するページを作成しました。入力する機能を作成するときは、forms.pyクラスを作成し、ひとまとめにすると扱いやすくなります。また、追加後はそのページにいる必要がないためリダイレクトしましょう。
Part5では、ToDoを削除するページを作成します。トップページに削除ボタンを追加したり、URLの設定が少し特殊になったりします。
最後までお読みいただきありがとうございます。
スポンサードサーチ