ProgateのNode.jsコースではお買い物リストアプリを作るのですが、これと全く同じものをDjangoで作ってみます。
Djangoでのアプリ開発の一連の流れを整理するために記していきます。
HTMLとCSS、PNG形式画像は使い回しで、一部をDjango用のタグに変えます。
#前回のおさらい
お買い物アイテム一覧が表示されるListページを作成をしました。
今回は、新しい買い物リストを作成するためのNewページを作っていきます。
#Newページの作成
ブラウザにデータを入力して、データベースに追加するページを作っていきます。
CreateViewという新たにレコードを追加するフォームを提供するビューを使っていきます。
まずは、HTMLファイルを作成します。
例のごとく、静的ファイル、CSSを読み込むためのタグ、index.htmlにリンクするためのurlタグをそれぞれ挿入していきます(☆1)。
☆2は重要です。Djangoはcsrf_tokenというテンプレートをformにつけることをルールとしています。
csrf_tokenはインターネット・バンキングなどにおけるワンタイムパスワードのようなイメージで、そのパスワードを持っていない状態では処理を行うことができないようになっています。
formには必ず{% csrf_token %}
を入れましょう!(☆2)
☆3の部分を見ていきます。
formタグの中の{{ form.item }}
の部分はDjangoのテンプレートを使った入力フォームです。データベースのitemフィールドに追加していくため、form.item
としています(☆3)。
{% load static %} <!--☆1-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LIST APP</title>
<link rel="stylesheet" href="{% static 'list/style.css' %}"> <!--☆1-->
</head>
<body>
<header>
<a href="{% url 'list:top' %}" class="header-logo">LIST APP</a> <!--☆1-->
</header>
<div class="container">
<div class="container-header">
<h1>買い物リスト作成</h1>
</div>
<div class="item-form-wrapper">
<p class="form-label">買うもの</p>
<form action="" method="post">{% csrf_token %} <!--☆2-->
{{ form.item }} <!--☆3-->
<input type="submit" value="作成する">
</form>
</div>
<a href="{% url 'list:index' %}" class="cancel-button"></span>もどる</a> <!--☆1-->
</div>
</body>
</html>
お決まりのviews.pyとurls.pyにコードを追加していきます。
views.pyから。
おさらいをするとCreateViewは新しいレコードを追加していくフォームです。
views.pyの中でCreateView
をimportして、ListNew
というclassを作成して、その中で継承します(☆4)。続いてtemplate_name
で使うHTMLファイルをnew.html
に、使うデータベースをListModel
に、データベースの中の使うフィールドをitem
フィールドに設定します(☆5)。
☆6のsuccess_url = reverse_lazy()
について見てみます。success_url
はフォームが正常に処理されたとき、登録されたURLにリダイレクトされます。formの「作成する」ボタンが押されると、views.pyファイルのreverse_lazy
で指定したname情報が照合されます。そして、合致した場合に対応するviewを呼び出します。この場合だと、「作成する」ボタンを押すとListページ(index.html)に移ります。reverse_lazy
で指定することにより、views.py→urls.py→URLという逆引き形式でURLを呼び出せます。
from django.shortcuts import render
from django.views.generic import TemplateView, ListView, CreateView # ☆4
from .models import ListModel
from django.urls import reverse_lazy # ☆6
class ListTop(TemplateView):
# top.htmlをレンダリング
template_name = 'list/top.html'
class ListIndex(ListView):
# index.htmlをレンダリング
template_name = 'list/index.html'
model = ListModel
class ListNew(CreateView):
# new.htmlをレンダリング
template_name = 'list/new.html' # ☆5
model = ListModel # ☆5
fields = ['item'] # ☆5
success_url = reverse_lazy('list:index') # ☆6
urls.pyファイルにコードを追加して、views.pyのListNewクラスを読み込むようにします(☆7)。
from django.urls import path
from .views import ListTop, ListIndex, ListNew
# URLパターンを逆引きできるように名前をつける
app_name = 'list'
urlpatterns = [
# リクエストされたパス部分が''に合致した場合、views.pyのListTopクラスをインスタンス化する
path('', ListTop.as_view(), name='top'),
# リクエストされたパス部分が'index'に合致した場合、views.pyのListIndexクラスをインスタンス化する
path('index/', ListIndex.as_view(), name='index'),
# リクエストされたパス部分が'new'に合致した場合、views.pyのListNewクラスをインスタンス化する
path('new/', ListNew.as_view(), name='new'), # ☆7
]
#Listページの修正
ListページからNewページに飛べるようにタグを加えておきます(☆8)。
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LIST APP</title>
<link rel="stylesheet" href="{% static 'list/style.css' %}">
</head>
<body>
<header>
<a href="{% url 'list:top' %}" class="header-logo">LIST APP</a>
</header>
<div class="container">
<div class="container-header">
<h1>買い物リスト</h1>
<a href="{% url 'list:new' %}" class="new-button">+ 新規登録</a> <!--☆8-->
</div>
<div class="index-table-wrapper">
<div class="table-head">
<span class="id-column">ID</span>
<span>買うもの</span>
</div>
<ul class="table-body">
{% for object in object_list %}
<li>
<div class="item-data">
<span class="id-column">{{ forloop.counter }}</span>
<span class="name-column">{{ object.item }}</span>
</div>
<div class="item-menu">
<form action="/delete/<%= item.id %>" method="post">
<input type="submit" value="削除">
</form>
<a href="/edit/<%= item.id %>">編集</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
</body>
</html>
これでお買い物リストにアイテムを新規作成するためのページができました。
試しに「とまと」を登録してみます。
ちゃんと登録されました!
次はリストを更新するためのページを作っていきます!
Part6に続きます!