この記事は以下のターゲットを対象としています。
★5 Django の開発経験が 3 年以上。
★4 Django の開発経験が 1 年以上。
★3 WEB サイト開発経験あり。これから Django を学習します。
★2 Python 初級者。簡単なプログラムコードが書けます。
★1 プログラミング未経験。
こんにちは、グローバルウェイの大坪です。
今回も前回に引き続きDjangoのクラスベースビューをご紹介します。クラスベースビューは、ビューをクラスとして表現する方法です。Djangoでは様々な種類のクラスベースビューが用意されているので、継承して使用することで簡単に画面を作成することができます。今回は更新系であるCreateView/UpdateView/DeleteViewを使ってみたいと思います。ソースコードは過去のブログのもの継続して使用しています。
第1回:はじめてのDjango~フレームワークとしての基本を知ろう~
第2回:はじめてのDjango~「DjangoでのDB操作」マイグレーション編
第3回:はじめてのDjango~「DjangoでのDB操作」ORMでのCRUD操作編
第4回:はじめてのDjango~クラスベースビューを使ってみる~
〔CreateViewを使ってみる〕
CreateViewを使用すると、登録画面を簡単に作成できます。まずはview.pyを記述します。変数に登録したいモデルと登録画面のテンプレート、使用するフォームを設定します。(フォームについては後ほど説明します。)
form_validはバリデーションが成功した際に呼ばれる関数なので、オーバーライドすることで処理をカスタマイズできます。作成者と更新者は画面で入力しないので、ここで値を設定します。(ログイン機能が実装されていないので、固定値を渡しています。)
登録に成功した際のリダイレクト先はsuccess_urlで設定しますが、今回は作成したモデルの詳細画面を表示したいのでget_success_urlをオーバライドしています。
【view.py】 class BlogCreateView(CreateView): model = Blog form_class = BlogForm template_name = ‘blog_create.html’ def form_valid(self, form): user_obj = User.objects.get(id=2) form.instance.created_by = user_obj form.instance.updated_by = user_obj return super().form_valid(form) def get_success_url(self): return reverse_lazy(‘detail’, kwargs={‘pk’: self.object.pk}) |
次にFormを記述します。Formには登録画面で表示したい項目の定義やバリデーションを記述します。今回はModelFormを継承しているので、モデルで定義している制約でバリデーションが行なわれます。また、各fieldでlabelを指定して画面での項目名を日本語にしています。Metaクラスのfieldsで表示させる項目を定義しています。
【form.py】 from django import forms from blog.models import Blog class BlogForm(forms.ModelForm): title = forms.CharField(label=’タイトル’) content = forms.CharField(label=’内容’, widget=forms.Textarea) class Meta: model = Blog fields = [‘title’, ‘content’] |
最後にテンプレートとurls.pyを記述して、登録画面は完成です。入力項目はformを使用して表示します。下記の記述をするとtable表示できます。
【blog_create.html】 <body> <h1>ブログ新規作成</h1> <form method=”post”> {% csrf_token %} <table> {{ form.as_table }} </table> <button class=”create_button” type=”submit”>保存</button> </form> </body> |
【urls.py】 from django.urls import path from blog.views import BlogListView, BlogDetailView, BlogCreateView, BlogUpdateView, \ BlogDeleteView urlpatterns = [ path(“list/”, BlogListView.as_view(), name=”list”), path(“<int:pk>/”, BlogDetailView.as_view(), name=”detail”), path(“create/”, BlogCreateView.as_view(), name=”create”), ] |
http://127.0.0.1:8080/blog/create/にアクセスすると登録画面が表示できました。
各項目を入力して保存ボタンを押すと、作成されたブログの詳細画面に遷移します。
画面遷移で登録画面を表示できるよう、一覧画面のテンプレートを修正して登録画面へのリンクを置いておきます。
【blog_list.html】※途中省略 <body> <h1>ブログ一覧</h1> <table>※省略</table> <a class=”create_button” href=”{% url ‘create’%}”>新規作成</a> </body> |
〔UpdateViewを使ってみる〕
UpdateViewを使用すると、編集画面を簡単に作成できます。まずはview.pyを記述します。CreateViewの時と同じように変数に編集したいモデルと編集画面のテンプレート、使用するフォームを設定します。
form_validは更新日時を指定し、get_success_urlは登録画面と同じように詳細画面のURLを返却するよう記述します。
【views.py】 class BlogUpdateView(UpdateView): model = Blog form_class = BlogForm template_name = ‘blog_update.html’ def form_valid(self, form): form.instance.updated_at = datetime.now() return super().form_valid(form) def get_success_url(self): return reverse_lazy(‘detail’, kwargs={‘pk’: self.object.pk}) |
テンプレートは登録画面とほぼ同じなので割愛します。(タイトルを編集にしただけです。)最後にurls.pyを記述すると編集画面は完成です。
【urls.py】 from django.urls import path from blog.views import BlogListView, BlogDetailView, BlogCreateView, BlogUpdateView, \ BlogDeleteView urlpatterns = [ path(“list/”, BlogListView.as_view(), name=”list”), path(“<int:pk>/”, BlogDetailView.as_view(), name=”detail”), path(“create/”, BlogCreateView.as_view(), name=”create”), path(“update/<int:pk>/”, BlogUpdateView.as_view(), name=”update”), ] |
http://127.0.0.1:8080/blog/update/8にアクセスすると編集画面が表示できました。
各項目を編集して保存ボタンを押すと、値が編集された状態で詳細画面が表示されます。
画面遷移で編集画面を表示できるよう、詳細画面のテンプレートを修正して編集画面へのリンクを置いておきます。
【blog_detail.html】※途中省略 <body> <h1><span>{{ object.title }}</span></h1> <p class=”created”>作成日: {{ object.created_at }}</p> <p class=”created”>作成者: {{ object.created_by }}</p> <p class=”content”>{{ object.content }}</p> <a class=”create_button” href=”{% url ‘update’ pk=object.pk %}”>編集</a> </body> |
〔DeleteViewを使ってみる〕
DeleteViewを使用すると簡単に削除画面を作成できます。まずはview.pyを記述します。モデル、テンプレート、成功した際のリダイレクト先を設定します。
【view.py】 class BlogDeleteView(DeleteView): model = Blog template_name = ‘blog_delete.html’ success_url = reverse_lazy(‘list’) |
次にテンプレートを記述します。DeleteViewでは取得したオブジェクトは変数objectで渡されます。
【blog_delete.html】※body以外は省略 <body> <h1>ブログ削除</h1> <p>本当にタイトル「{{ object.title }}」を削除しますか?</p> <form method=”post”> {% csrf_token %} <button class=”delete_button” type=”submit”>削除</button> </form> </body> |
最後にurls.pyを記述して削除画面は完成です。
【urls.py】 urlpatterns = [ path(“list/”, BlogListView.as_view(), name=”list”), path(“<int:pk>/”, BlogDetailView.as_view(), name=”detail”), path(“create/”, BlogCreateView.as_view(), name=”create”), path(“update/<int:pk>/”, BlogUpdateView.as_view(), name=”update”), path(“delete/<int:pk>/”, BlogDeleteView.as_view(), name=”delete”), ] |
http://127.0.0.1:8080/blog/delete/8/にアクセスすると、削除画面を表示することができました。
削除ボタンを押すと、一覧画面に遷移し該当のブログが削除されていることが確認できます。
画面遷移で削除画面を表示できるよう、詳細画面のテンプレートを修正して削除画面へのリンクを置いておきます。
【blog_detail.html】※途中省略 <body> <h1><span>{{ object.title }}</span></h1> <p class=”created”>作成日: {{ object.created_at }}</p> <p class=”created”>作成者: {{ object.created_by }}</p> <p class=”content”>{{ object.content }}</p> <a class=”create_button” href=”{% url ‘update’ pk=object.pk %}”>編集</a> <a class=”delete_button” href=”{% url ‘update’ pk=object.pk %}”>削除</a> </body> |
〔まとめ〕
クラスベースビューを使用すると簡単に更新系の画面を作成することができます。前回・今回紹介したようにDjangoでは様々なクラスベースビューが用意されているので、やりたいことに応じて適切にクラスを選択して実装を行いましょう。