Djangoではクラスベースビューという、簡単にビューを実装できる仕組みがあります。
また、クラスベースビューの中にはデータ操作に必須のCreateView、ListView、UpdateView、DeleteViewというクラスがあります。
これらのクラスがなぜ必須なのか?をCRUDという視点で解説し、それぞれのクラスベースビューを順番に実装していきます。
一気に実装するわけではないので、少しずつ使えるようになりましょう。
この記事では前編として、CreateView、ListViewについて解説しています。
ちなみに、Djangoに必要なHTML/CSS、JavaScriptなどのWeb開発系言語は侍テラコヤという学習サイトで無料で学習できるのでおすすめですよ!
クラスベースビューとは
クラスベースビュー(汎用クラスビュー)とは、Djangoで標準で用意されているviewを実装するためのクラス、あるいはそれを継承した自前で作成したクラスを指します。
Djangoでは、ビューを実装するためにさまざまな機能のクラスが事前に用意されています。
開発者は、それらのクラスを継承したクラスを定義することでビューを実装することが可能です。
例えば、モデルのデータをフォーム形式で新規追加するCreateViewや、モデルのデータを一覧表示するためのListViewなどがあります。
以下、代表的なクラスベースビューをまとめます。
クラス名 | 説明 | 定義場所 |
---|---|---|
View | 最も基本的なクラスベースビュー。すべてのクラスベースビューはこのViewクラスを継承している。クラスベースビューを実装する際は、このViewクラスよりも、さまざまな機能に特化した以下のクラスを継承することが多い。 | django.views.generic.base.View |
TemplateView | Viewに続いて基本的なクラスベースビュー。特徴は、クラス変数template_nameにテンプレートファイル名を設定すると、自動的にそのテンプレートを使用する(RedirectView以外の以下のクラスはすべて同機能あり)。get時の動作しか定義されていないため、postなどは自前で作成する必要がある。 | django.views.generic.base.TemplateView |
RedirectView | リダイレクト動作に特化したクラスベースビュー。デフォルトでは、すべてのHTTPメソッド(POSTやPUTなど)も、GET時の動作に置き換えられる。 | django.views.generic.base.RedirectView |
FormView | フォーム作成に特化したクラスベースビュー。クラス変数form_classに設定したフォームの表示や、POST時のバリデーションなどが実装済み。 | django.views.generic.edit.FormView |
CreateView | データベースにデータを新規追加することに特化したクラスベースビュー。モデルに応じたフォームを表示し、POST時にデータを登録する。 | django.views.generic.edit.CreateView |
UpdateView | データベースのデータを更新することに特化したクラスベースビュー。既存データの修正が可能。 | django.views.generic.edit.CreateView |
ListView | データベースのデータを一覧表示することに特化したクラスベースビュー。データ数が多い場合、ページを分けるページネーションの機能も搭載。 | django.views.generic.list.ListView |
DeleteView | データベースのデータを削除することに特化したクラスベースビュー。データ削除時の確認画面を表示できる。 | django.views.generic.edit.DeleteView |
DetailView | データベースのデータ詳細を表示することに特化したクラスベースビュー。ListViewでは主要なカラムのみ表示し、DetailViewで詳細を表示する使い分けが可能。 | django.views.generic.detail.DetailView |
CRUDとは?
CRUDとは、「生成(Create)」「参照(Read)」「更新(Update)」「削除(Delete)」の頭文字をまとめたものを表します。
これらは、データ操作の手法を表していて、データを扱う場合はこれら4種類の操作が正しく実装されている必要があります。
例えば、Createがなければ、データの追加ができませんし、Updateがなければ一度登録したデータを更新することができなくなります。
このようにCRUDは、データを扱うアプリケーションでは必須の機能です。
共通設定
次章からCreateView、ListView、UpdateViewを実装していきますが、models.pyとurls.pyは共通になるので先に定義しておきます。
モデル設定
モデルは以下のように定義します。
内容はとても簡単で、文字列のnameと、int型のageフィールドがあるだけです。
from django.db import models
class Member(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
urls.py
urls.pyは、CreateView、ListView、UpdateView、DeleteViewを追加するたびに書き加えていくのですが、いちいち挟んでいると話の本質とそれるので先にまとめて載せておきます。
記事の内容に沿って、順を追ってクラスベースビューを実装していく場合は、該当する行を順次追加していって下さい。(最初はpath=’create/’の行のみ、ListViewを追加するときにpath=’list/’の行を追加する、といった感じです。)
from django.urls import path
from . import views
urlpatterns = [
path('create/', views.MemberCreateView.as_view(), name='create'),
path('list/', views.MemberListView.as_view(), name='list'),
path('<int:pk>/update/', views.MemberUpdateView.as_view(), name='update'),
path('<int:pk>/delete/', views.MemberDeleteView.as_view(), name='delete'),
]
CreateViewの使い方
データがないことには更新も削除もできないので、まずはデータ作成のCreateViewから実装していきましょう。
CreateViewとは
繰り返しになりますが、CreateViewはデータの新規登録を行う機能に特化したクラスベースビューです。
CreateViewを継承したクラスを使えば、簡単にデータの登録フォームを実装できます。
CreateViewの使い方
views.py
CreateViewを実装します。
今回は紹介程度にしたいので、最低限の機能しか使用しません。
逆にいえば、これだけで実装ができるのか、とその簡単さに驚くかもしれません。
from django.views.generic.edit import CreateView
from .models import Member
class MemberCreateView(CreateView):
model = Member
fields = "__all__"
models.pyで定義したモデルMemberのデータを登録するためのMemberCreateViewを定義しています。
メソッドは何も定義しておらず、クラス変数modelとfieldsを設定しているだけです。
これらのクラス変数の意味をまとめます。
クラス変数 | 内容 |
---|---|
model | データを登録する対象のモデル名 |
fields | データを登録するフィールドのリスト (”__all__”を指定するとすべてのフィールドが対象) |
modelには、Memberクラスを設定し、fieldsには”__all__”を設定しています。
このように”__all__”を指定することで、すべてのフィールドが対象になります。
個別に設定するには、[“name”, “age”]のように、フィールド名のリストで指定してください。
このfieldsに指定されたフィールドが、フォームとして表示され、登録できるようになります。
テンプレート
クラスベースビューでは、クラス変数template_nameにテンプレートHTMLのファイル名を指定することが多いですが、CreateViewの場合は{モデル名}_form.htmlというファイルを自動で検出してくれます。(今回の場合はmember_form.html)
正確には、クラス変数template_name_suffixがあり、{モデル名}{template_name_suffix}.htmlというファイルを探します。
デフォルトではtemplate_name_suffix=”_form”となっているので、解くに理由がなければ{モデル名}_form.htmlでよいです。(モデル名は大文字・小文字は問いません)
テンプレートHTMLは以下のようにしています。
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
ブラウザ表示
開発サーバーを起動し、ブラウザ表示を確認します。
上のようにNameとAgeの入力フォームが表示されました。
2つの変数を設定するだけで実現できるのは驚きですね。
ちなみに、今の状態で登録ボタンを押してもPOST時の動作を定義していないので、エラーになります。
では、登録ボタンを押したら登録済みのデータの一覧を表示するようにしましょう。
そこで、ListViewを使います。
ListViewの使い方
ListViewとは
ListViewは、登録済みデータの一覧(リスト)を表示することに特化したクラスベースビューです。
CreateViewなどで登録したデータを、一覧表示できます。
データ数が多いときは、一定の数ごとにページを分けるページネーションも可能です。
ListViewの使い方
views.py
ListViewも、CreateViewのときと同様にいくつかのクラス変数を指定するだけで使えます。
最低限の機能だけでよければ、以下のようにmodelに一覧表示させたいモデルのクラスを設定するだけです。
from django.views.generic.edit import CreateView
from django.views.generic.list import ListView
from .models import Member
class MemberCreateView(CreateView):
model = Member
fields = "__all__"
success_url = reverse_lazy('list')
class MemberListView(ListView):
model = Member
また、CreateViewで登録ボタンを押したら一覧表示されるようにしたいので、MemberCreateViewに新たなクラス変数success_urlを設定しています。
reverse_lazy({URL名})とすることで、POST時にそのURLへリダイレクトされるようになります。
(URL名は、urls.pyで指定したname=の部分)
テンプレート
ListViewも、CreateViewのようにテンプレート名はデフォルトのものがあり、{モデル名}_list.htmlです。
template_name_suffixに”_list”が設定されているためです。
テンプレートは以下のようにします。
<h1>Members</h1>
<ul>
{% for member in object_list %}
<li>
{{ member.name }} - {{ member.age }}
</li>
{% empty %}
<li>データがありません</li>
{% endfor %}
<a href="{% url 'create' %}">登録ページ</a>
ListViewでは、モデルのデータのリストをobject_listというコンテキストとして所持します。
{% for member in object_list %}の部分は、object_listから1つずつデータを取得してループする処理です。
取得したデータを<li>タグで箇条書きにして表示します。
また、データが1つもない(object_listが空)場合は{% empty %}以下の文が実行され、ブラウザに「データがありません」と表示されます。
最後の行は、登録ページに戻るためにリンクです。
ブラウザ表示
まずは、データが何も登録されていない状態だと思うので、http://127.0.0.1/list/にアクセスすると、以下のような表示になると思います。
では、データが登録されたときを見ていきましょう。
最初のCreateViewのページ(http://127.0.0.1/create/)で、適当なデータを登録してみて下さい。
すると、登録ボタンを押すと登録したデータが表示されると思います。
無事、登録したデータが表示されました。
また登録ページに戻って、いくつかデータを登録すると、その度にリストが増えることが確認できると思います。
ページネーション
ListViewでは、1つのページに表示するデータ数を制限することもできます。
今回はページネーションの必要最低限な部分に関して説明します。
その他ページネーションに関する詳しい説明は、以下の記事で行なっていますのであわせてご参照ください。
ListViewでは、クラス変数pagenate_byに1ページあたりに表示させたいデータ数を設定するだけでページネーションを実現できます。
class MemberListView(ListView):
model = Member
paginate_by = 5
テンプレートはややこしいですが、以下のようにすることでページ機能が実現できます。
<h1>Members</h1>
<ul>
{% for member in object_list %}
<li>
{{ member.name }} - {{ member.age }}
</li>
{% empty %}
<li>データがありません</li>
{% endfor %}
</ul>
<a href="{% url 'create' %}">登録ページ</a>
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">« 最初のページ</a>
<a href="?page={{ page_obj.previous_page_number }}">前のページ</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">次のページ</a>
<a href="?page={{ page_obj.paginator.num_pages }}">最後のページ »</a>
{% endif %}
</span>
</div>
page_objに、ページネーション用のオブジェクトが格納されていて、page_obj.has_previousメソッドが真のとき、前ページが存在し、page_obj.has_nextメソッドが真のとき、次のページが存在します。
さらに、page_obj.numberは現在のページの番号、page_obj.paginator.num_pagesは全ページ数を表します。
ちなみに、ブラウザ表示は以下のようになります。(データを7つ登録しました)
まとめ
今回はCreateView、ListViewを実装し、その機能を確認しました。
どちらもメソッド定義など必要なく、いくつかのクラス変数を設定するだけで実装可能で、とても簡単だったと思います。
次回は、残りのUpdateView、DeleteViewについて解説します。
Djangoはまだまだたくさんの機能が盛り沢山です。
このサイトでは、他にもさまざまな解説記事を載せているので、ぜひ参考にしてください!
なお、侍テラコヤという学習サイトでは、DjangoをはじめPythonやHTML/CSS/JavaScriptを無料で学ぶことができます!
メールアドレスだけで簡単に無料登録できるのでぜひ覗いてみてくださいね。
\無料プランを無期限で試す/
メールアドレスだけで10秒で登録!
また、独学だけでなく、人から教えてもらうというのも大切です。
以下の記事ではDjangoが学べるプログラミングスクールを、目的別におすすめを紹介していますので、こちらもぜひご検討ください。
コメント