今回はCreateView編です。
今までTemplateViewを用いてListView、DetailViewを作成してまいりました。
その1-TemplateViewを使ってみよう!IndexView編
その2-TemplateViewをつかってみよう!Detailview編
お店の一覧、お店の詳細ページを表示ができるようになっている状態の続きと致します。
自分で好きなデータを追加できるって掲示板みたいで楽しいですよね!!
(見慣れない技術の解説)forms.pyでフォームの定義をおこなう
ここであらたなフォームという技術が現れました。
このforms機能はお仕事ではかなり使われることが多いので、慣れておくことを絶対にお勧めしています。
これは何なのかというと、pythonでこのform部分を作ってしまい、モデルと連動してhtmlの<form></form>を作成することになります。
最終的にwebサイトのフォーム部分を表示させることが目的となっていますので、怖がらずで大丈夫ですよ!
編集するファイルはこちら
mysite
│ db.sqlite3
│ manage.py
├─mysite
│ │ settings.py
│ │ urls.py
└─test_app
│ admin.py
│ apps.py
│ models.py
│ tests.py
│ urls.py(ここをルーティング設定のために編集)
│ views.py(ここをCreateView設定のために編集)
│ forms.py(ここにお店追加の投稿フォームclassを作成)
├─migrations
└─templates
└─test_app
└─list.html(ここにお店追加のリンクを表示)
detail.html
form.html(お店追加の投稿フォームを表示)
ルーティング設定
このURLでお店の作成ページにリンクできるように設定します。
http://localhost:8000/create
test_appのurls.pyにルーティングを設定します。
from django.urls import path
from . import views
app_name = 'test_app'
urlpatterns = [
path('index/',views.IndexView.as_view(),name='index'),
path('<int:pk>/',views.DetailView.as_view(),name='detail'),
path('create/',views.CreateView.as_view(),name='create'),#(ここを追加)
]
解説:app_name
とは、どのアプリ名に対してのルーティングファイルであるか指定する必要があります。ページ上のリンク(htmlで書かれたページのaタグで書かれたリンク)で<a href="{% url 'test_app:create' %}">
と記述するため、test_app
とアプリ名を設定する必要があります。
また、path('create/',views.CreateView.as_view(),name='create')
ではcreate/のURLでviews.pyのCreateViewを呼び出しています。as_view()はテンプレートビューをビューとして扱うため使用されています。このas_view()を付けることによりビュー定義の記述がぐっと楽になります。テンプレートビュー限定のメリットですね。
CreateViewをviews.pyに設定
from django.views import generic
from .models import Shop
from .forms import ShopCreateForm #ここを追加
# Create your views here.
class IndexView(generic.ListView):
model = Shop
template_name = 'test_app/list.html'
class DetailView(generic.DetailView):
model=Shop
template_name = 'test_app/detail.html'
class CreateView(generic.CreateView):#ここ以降を追加
model = Shop
form_class = ShopCreateForm
template_name = "test_app/form.html"
success_url = "/index"
解説:form_class
にforms.pyで投稿フォーム用に今回作成するフォームクラスであるShopCreateForm
を指定しています。
ちゃんとimport ShopCreateForm
を忘れずにお願いします。
views.pyとforms.pyを作成し、行ったり来たりするため、慣れるまで時間がかかりますが頑張りましょう!焦らず無理せず。
きっと慣れてさらに先に進めます!
お店投稿フォームをforms.pyに作成
forms.pyが作成されていない場合、新たに作成する場合があります。作成する場所はtest_appの直下です。views.pyやmodels.pyと同じレベルに作成します。
forms.pyはこのようになります。
from django import forms
from .models import Shop
class ShopCreateForm(forms.ModelForm):
class Meta:
model = Shop
fields = ("name","tell_num","address")
解説:forms.ModelFormとは、フォームを作成するためのdjangoの機能となっています。
モデルで定義されているフィールドをそのまま使います。
そのなかで、fields
にてフォームで表示させるフィールドを選び、絞ることができます。
お店のデータを投稿したい場合、すでにShopのフィールドは作成されています。実際にmodels.pyの内容はこちらで、name
やtell_num
、address
、created_at
などフィールドが作成されています。
from django.db import models
# Create your models here.
class Shop(models.Model):
#各フィールドの定義
name = models.CharField('shopname',max_length=30)
tell_num = models.CharField('tell_number',max_length=13)
address = models.CharField('address',max_length=30)
created_at = models.DateTimeField(auto_now_add=True)
#admin画面の表示内容
def __str__(self):
return self.name
このShopクラスのフィールドをそのままforms.pyで使うことを意味しているのです。
ModelFormを用いると大変楽にフォームページを作成できるのです!
投稿ページのform.htmlを作成
<!DOCTYPE>
<html>
<head>
</head>
<body>
<p>お店の作成</p>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">save</button>
</form>
</body>
</html>
解説:<form method="post">
でフォームタグを作成しています。
{% csrf_token %}
はフォームデータに改ざん防止の特殊な何かのデータを添えて送信するもので、必須です。
これを入れないと、djangoがエラーとなるため、必ず入れましょう。
{{ form.as_p }}
はforms.pyで作成したShopCreateFormをviews.pyのform_class
で指定していたため、html側ではform
と記述するだけでフォームが呼び出せます。form
と書く、と刷り込ませて良いです!
<button type="submit">save</button>
ではデータ送信ボタンを作成しています。」
「お店の投稿」リンクを一覧ページに作成
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>一覧の表示</p>
<p><a href="{% url 'test_app:create' %}">お店の追加</a></p><!-- この行を追加 -->
<table>
<tr>
</tr>
{% for shop in shop_list %}
<tr>
<td>{{ shop.name }}</td>
<td><a href="{% url 'test_app:detail' shop.pk %}">詳細</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
解説:お店の追加ページへリンクするためにリンクを書いています。パスはtest_app
というアプリ名のcreate
を指定しています。
formの表示の確認を行う
「お店の追加フォーム画面」で団子屋という名前のお店を追加してみます。
お疲れさまでした✨
最後に
データ追加のための設定は必ずと言っていいほど重要なdjangoスキルとなるでしょう。CreateViewを用いてスピーディに作成ができることでかなりDjangoに慣れているといえると思います。
3つくらい自分でアプリを作成してみれば、データの追加、詳細、一覧が含まれるような、お店掲示板、日記などのアプリケーションが作成できるようになっていると思います。
わからないところや質問など受け付けておりますので、一緒に頑張ってゆきましょう!