今回のお題
今回はdjangoの汎用ビューの一つであるUpdateView
についてとりあげます。
最近クラスベースビューを使い始めたのですが、その過程で今回のテーマであるUpdateViewに遭遇したので自分用に残しておきます。
なお、本記事ではクラスベースビューそのものについての解説は行いませんのでご了承ください。
目次
- 汎用ビューとは
- UpdateViewの設定項目
- 実装例
- まとめ
汎用ビューとは
まずは汎用ビューそのものの定義からしておきます。
クラスベースビューでは一般的にTemplateView
クラスを継承させて、新たなビュークラスを作成します。
class HomeView(TemplateView):
template_name = "home.html"
しかしTemplateViewクラスでは設定できる属性値やメソッドが限られており、そのために以下のような問題を抱えています。
- 新規登録を行う際に、成功時と失敗時で遷移先を切り替えることが難しい。
- フォームとDBの間での情報の受け渡しを全て記述しているとコード量が膨大になってしまう。
これらの問題を解消するために、djangoでは汎用ビュー
と呼ばれるTemplateViewのサブクラスが用意されています。
汎用ビューは独自の属性値やメソッドを持っており、それらを設定することによって上記の問題を解決することができるようになっています。
今回取り上げるUpdateViewもその一つであり、必要な値を設定することでレコード更新に必要な項目、すなわち成功時の遷移先urlや利用するフォームなどを簡単に指定することができるようになっています。
UpdateViewの設定項目
では、UpdateViewに設定すべき項目について見ていきます。
- template_name
- 遷移先のテンプレートを指定するための変数。
- 全てのTemplateViewクラスで設定可能。
- model
- レコード更新をかけるモデルを指定するための変数。
- ここで指定したモデルに関しては、モデル名をスネークケースに変換したものが自動的にcontextに追加される(例:Bookモデルであればcontext["book"]に格納される)。
- 後述のform_classにてModelFormクラスを指定している場合であっても、この変数の設定は必須。
- form_class
- テンプレートに表示するフォームクラスを指定するための変数。
- ここで指定したフォームクラスについても、contextにformというキーで格納される。
- 先述のmodel属性とこのform_class属性に関しては大元のTemplateViewには設定されていないので、それらを設定したければ汎用テンプレートを使う必要がある。
- fileds
- フォームに表示するフィールド名を指定するための属性値。
- 上記のform_classとどちらか一方を指定(両方指定するとエラーになる)。
- get_success_url
- レコードの更新に成功した場合の遷移先を指定するための関数。
- こちらも大元のTemplateViewクラスには存在しない。
これらを指定すればいつもより簡単にレコード更新が実装できそうですね。
実装例
では、上記の項目を使ってレコード更新機能を実装していきます。
class Book(models.Model):
title = models.CharField(max_length=30)
author = mdels.CharField(max_length=30)
class BookForm(ModelForm):
class Meta:
fields = "__all__"
from django.views.generic.edit import UpdateView
class BookUpdateView(UpdateView):
template_name = "book/update.html"
model = Book
form = BookUpdateForm
def get_success_url(self):
return reverse("book:show", kwargs={"pk":self.object.pk})
urlpatterns = [
path("update/<int:pk>", views.BookUpdateView.as_view(), name="update"),
]
これで実装完了です。
ちなみに、以下の部分でパラメータ名をpk
以外にするとエラーになります。
def get_success_url(self):
return reverse("book:show", kwargs={"pk":self.object.pk})
path("update/<int:pk>",
まとめ
以上でUpdateViewを用いたレコード更新機能が実装できました。
まとめとしては、
- UpdateViewには
model
やget_success_url
などの独自の属性・関数が定義されているので、それらを利用すると実装が楽になる。 - パラメータの受け渡しは必ず
pk
で行う。
というところですね。
汎用ビューには他にも新規登録や詳細表示などに特化したものもあるので、そちらについてもいずれまとめようと思います。