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の設定が少し特殊になったりします。

 

最後までお読みいただきありがとうございます。


スポンサードサーチ