クラスベースのビュー

django Published at March 9, 2025, 7:47 a.m. by admin@senrigan.org

クラスベース関連のドキュメント読んだ。

クラスベースビュー

ListViewを継承するxxViewクラスを書いて、urlpatternsに登録する。HEADするだけならテンプレートさえいらない。5分でできる。

curl -I http://127.0.0.1:8000/books/

HTTP/1.1 200 OK
Date: Sun, 09 Mar 2025 07:49:43 GMT
Server: WSGIServer/0.2 CPython/3.12.3
Last-Modified: Sun, 09 Mar 2025 04:41:57 GMT

asyncについて少々。


クラスベースビュー入門

  • クラスベースのビューは、HTTPメソッドごとに条件を使ってかき分けることなく、それぞれ独立したメソッド、get(), post(), ...を割り当てる
  • 多重継承を使ってコードベースを再利用可能なコンポーネントに分解する

クラスベースのビューにすると、urls.pyでよく見かける.as_view()がなんで必要になるのか?URLリゾルバがそう期待してるから。

as_view()の呼び出し時に、dictで渡してクラス属性を更新できる。これもある種のデコレータ?

クラスはHTTPリクエストごとにインスタンス化されるが、as_view()はURLがインポートされる1度だけ。たぶんreverse_lazy()が必要な理由。

mixinの使用上の注意。例えばListView と ProcessFormView はそれぞれ View を基底クラスとしているけど、これらを同時に継承するクラスは機能しない。mixinを使う。

クラスのデコレーションについて。さっき出てきたURLconfでデコレートするやり方はインスタンスごとに適用されるので、あるビューのすべてのインスタンスに適用したい場合は、dispatch()を上書きして@method_decoratorをつける。


組み込みクラスベースの汎用ビュー

PublisherとAuthorとBookクラスがあって、ListViewを継承したPublisherListViewクラスを作ってそれをURLにフックするだけ。これだけでテンプレート内ではobject_listまたはpublisher_listを介してPublisherのリストオブジェクトにアクセスできる。テンプレート名もbooks/publisher_list.htmlで推論してくれる。

変数名はcontext_object_nameでも指定可能。

get_context_data()を上書きしてコンテキストを追加することも可能。

model = Publisherを指定することは、queryset = Publisher.objects.all()とするのと同じ。

get_queryset()を上書きして、例えばrequestパラメータやself.request.userによって動的にquerysetをフィルタリングすることも可能。


クラスベースのビューでフォームを扱う

  • GET
  • 無効なPOST
  • 有効なPOST

フォーム処理でよくある3つのHTTPリクエストについて、Djangoは汎用クラスを用意

FormViewはTemplateResponseMixinを継承するため、ここではtemplate_nameを使える。 今こここでハマってる。

これは、railsだったらscaffoldで自動生成してくれるけど、Djangoだと、仕組みは用意してあるので必要なら自分で書いてねってことか?

fields属性を何らかの形で設定しないとImproperlyConfigured発生。form_classとfields属性を同時に指定する場合も同様。

オブジェクトを作成したユーザーを追跡するには、CreateViewを継承したカスタムモデルを作って、form_valid()の中でsuper()呼ぶ前にcreated_byにself.request.user突っ込めばいい。

htmlで返すかjsonで返すか決めるのを、コンテンツネゴシエーションっていうの?


クラスベースのビューでmixinを扱う

力尽きる。