{"title":"クラスベースのビューでミックスイン (mixin) を使用する","version":"5.1","locale":"ja","docname":"topics/class-based-views/mixins","url":"/ja/5.1/topics/class-based-views/mixins/","canonical":"https://djangodocs.dev/ja/5.1/topics/class-based-views/mixins/","summary":"注意 これは発展的なトピックです。これらのテクニックについて詳しく読む前に、 Django のクラスベースビュー で動作のしくみを知っておくことをおすすめします。 Django のビルトインのクラスベースビューではたくさんの機能が準備されていますが、個別に使いたい機能もあるかもしれません。たとえば、HTTP…","html":"<h1>クラスベースのビューでミックスイン (mixin) を使用する<a class=\"heading-anchor\" href=\"#using-mixins-with-class-based-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<aside class=\"admonition admonition-caution\" role=\"note\">\n<p class=\"admonition-title\">注意</p>\n<p>これは発展的なトピックです。これらのテクニックについて詳しく読む前に、<a class=\"reference internal\" href=\"/ja/5.1/topics/class-based-views/\"><span class=\"doc\">Django のクラスベースビュー</span></a> で動作のしくみを知っておくことをおすすめします。</p>\n</aside>\n<p>Django のビルトインのクラスベースビューではたくさんの機能が準備されていますが、個別に使いたい機能もあるかもしれません。たとえば、HTTP レスポンスを生成するテンプレートをレンダリングするビューを記述したいとき、<a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/base/#django.views.generic.base.TemplateView\" title=\"django.views.generic.base.TemplateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateView</span></code></a> は使えない状況もあります; <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> ではテンプレートをレンダリングするだけで、<code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> のときはまったく異なる処理がしたいときなどです。この場合、<a class=\"reference internal\" href=\"/ja/5.1/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> を直接使えますが、コードが重複する結果となってしまいます。</p>\n<p>この理由から、Django は個別の機能を提供する多くの mixin を用意しています。たとえば、テンプレートのレンダリングは <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin\" title=\"django.views.generic.base.TemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code></a> でカプセル化されています。Django のリファレンスドキュメントには  <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins/\"><span class=\"doc\">すべてのミックスインの完全なドキュメント</span></a> があります。</p>\n<section id=\"context-and-template-responses\">\n<h2>コンテキストとテンプレートのレスポンス<a class=\"heading-anchor\" href=\"#context-and-template-responses\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>2 つの中心的なミックスイン (mixin) が用意されており、クラスベースビュー内のテンプレートを扱うインターフェースに一貫性を保ちやすくなっています。</p>\n<dl>\n<dt><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin\" title=\"django.views.generic.base.TemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code></a></dt><dd><p><a class=\"reference internal\" href=\"/ja/5.1/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> を返すビルトインビューは全て、 <code class=\"docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code> が提供する <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.render_to_response\" title=\"django.views.generic.base.TemplateResponseMixin.render_to_response\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code></a> メソッドを呼び出します。ほとんどの場合、これはあなたによって呼び出されます(たとえば、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/base/#django.views.generic.base.TemplateView\" title=\"django.views.generic.base.TemplateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateView</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a>)の両方で実装されている <code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> メソッドによって)。同様に、これをオーバーライドする必要はほとんどありませんが、Django テンプレートでレンダリングされていないものを返したい場合は、オーバーライドする必要があるでしょう。この例については、 <a class=\"reference internal\" href=\"#jsonresponsemixin-example\"><span class=\"std std-ref\">JSONResponseMixin の例</span></a> を参照してください。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code> 自体は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.get_template_names\" title=\"django.views.generic.base.TemplateResponseMixin.get_template_names\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_template_names()</span></code></a> を呼び出しますが、デフォルトではクラスベースのビューで <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.template_name\" title=\"django.views.generic.base.TemplateResponseMixin.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a> を検索します。他の2つのミックスイン (<a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectTemplateResponseMixin\" title=\"django.views.generic.detail.SingleObjectTemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectTemplateResponseMixin</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectTemplateResponseMixin\" title=\"django.views.generic.list.MultipleObjectTemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">MultipleObjectTemplateResponseMixin</span></code></a>) は、実際のオブジェクトを扱うときに、より柔軟なデフォルトを提供するためにこれをオーバーライドします。</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.ContextMixin\" title=\"django.views.generic.base.ContextMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ContextMixin</span></code></a></dt><dd><p>コンテキストデータが必要なすべての組み込みビュー、たとえばテンプレート (上述の <code class=\"docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code> を含む) をレンダリングするには、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.ContextMixin.get_context_data\" title=\"django.views.generic.base.ContextMixin.get_context_data\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code></a> を呼び出し、そこに含めたいデータをキーワード引数として渡してください。<code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code> は辞書を返します。<code class=\"docutils literal notranslate\"><span class=\"pre\">ContextMixin</span></code> ではキーワード引数を返しますが、辞書にさらにメンバーを追加するためにこれをオーバーライドすることはよく行われます。また、<a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.ContextMixin.extra_context\" title=\"django.views.generic.base.ContextMixin.extra_context\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">extra_context</span></code></a> 属性も使用できます。</p>\n</dd>\n</dl>\n</section>\n<section id=\"building-up-django-s-generic-class-based-views\">\n<h2>Django の一般的なクラスベースのビューを構築する<a class=\"heading-anchor\" href=\"#building-up-django-s-generic-class-based-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Djangoのクラスベースのジェネリックビューが、個々の機能を提供するミックスインからどのように構築されているか見てみましょう。オブジェクトの「詳細」ビューをレンダリングする <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> と、クエリセットから典型的にオブジェクトのリストをレンダリングし、オプションでページ分割する <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.list.ListView\" title=\"django.views.generic.list.ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> を考えます。これにより、単一のDjangoオブジェクトや複数のオブジェクトを扱う際に便利な機能を提供する4つのミックスインについて紹介します。</p>\n<p>ジェネリック編集ビュー (<a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView\" title=\"django.views.generic.edit.FormView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormView</span></code></a> と、モデル固有のビュー <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-editing/#django.views.generic.edit.CreateView\" title=\"django.views.generic.edit.CreateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">CreateView</span></code></a>, <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-editing/#django.views.generic.edit.UpdateView\" title=\"django.views.generic.edit.UpdateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">UpdateView</span></code></a>, <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-editing/#django.views.generic.edit.DeleteView\" title=\"django.views.generic.edit.DeleteView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DeleteView</span></code></a>) と日付ベースのジェネリックビューにもミックスインがあります。これらは <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins/\"><span class=\"doc\">ミックスインのリファレンス</span></a> で紹介されています。</p>\n<section id=\"detailview-working-with-a-single-django-object\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">DetailView</span></code>: Django の1つのオブジェクトを対象とするビュー<a class=\"heading-anchor\" href=\"#detailview-working-with-a-single-django-object\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>オブジェクトの詳細を表示するためには、基本的に2つの作業が必要です。まずはオブジェクトを検索し、それから適切なテンプレートと、そのオブジェクトをコンテキストとして、 <a class=\"reference internal\" href=\"/ja/5.1/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> を作成します。</p>\n<p>オブジェクトを取得するために、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> に依存しています。このクラスではリクエストURLに基づいてオブジェクトを見つけ出すメソッド <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_object\" title=\"django.views.generic.detail.SingleObjectMixin.get_object\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_object()</span></code></a> を提供しています(このメソッドでは URLConfで宣言されている <code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code> および <code class=\"docutils literal notranslate\"><span class=\"pre\">slug</span></code> キーワード引数を検索し、ビューの <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.model\" title=\"django.views.generic.detail.SingleObjectMixin.model\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">model</span></code></a> 属性、あるいは提供されている場合は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.queryset\" title=\"django.views.generic.detail.SingleObjectMixin.queryset\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">queryset</span></code></a> 属性からオブジェクトを検索します)。 <code class=\"docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code> はまた <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.ContextMixin.get_context_data\" title=\"django.views.generic.base.ContextMixin.get_context_data\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code></a> メソッドも提供しています。このメソッドでは、テンプレートレンダーに渡すコンテキストデータを提供するために、Django組み込みのクラスベースビュー全てで使われています。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> を作成するために、<a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectTemplateResponseMixin\" title=\"django.views.generic.detail.SingleObjectTemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectTemplateResponseMixin</span></code></a> を使用します。これは <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin\" title=\"django.views.generic.base.TemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code></a> を拡張し、上記のように <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.get_template_names\" title=\"django.views.generic.base.TemplateResponseMixin.get_template_names\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_template_names()</span></code></a> をオーバーライドします。実際にはかなり洗練されたオプションのセットを提供していますが、ほとんどの人が使用する主なものは <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;app_label&gt;/&lt;model_name&gt;_detail.html</span></code> です。<code class=\"docutils literal notranslate\"><span class=\"pre\">_detail</span></code> 部分は、サブクラス上の <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectTemplateResponseMixin.template_name_suffix\" title=\"django.views.generic.detail.SingleObjectTemplateResponseMixin.template_name_suffix\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_suffix</span></code></a> を別のものに設定することで変更できます。（例えば、<a class=\"reference internal\" href=\"/ja/5.1/topics/class-based-views/generic-editing/\"><span class=\"doc\">ジェネリック編集ビュー</span></a> は、作成および更新ビューに <code class=\"docutils literal notranslate\"><span class=\"pre\">_form</span></code> を、削除ビューには <code class=\"docutils literal notranslate\"><span class=\"pre\">_confirm_delete</span></code> を使用します。）</p>\n</section>\n<section id=\"listview-working-with-many-django-objects\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">ListView</span></code>: Django の複数のオブジェクトを対象とするビュー<a class=\"heading-anchor\" href=\"#listview-working-with-many-django-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>オブジェクトのリストもおおよそ同じパターンに従います。オブジェクトの (おそらくページ分割された) リスト、典型的には <a class=\"reference internal\" href=\"/ja/5.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code></a> が必要で、次にそのオブジェクトのリストを使って、適切なテンプレートで <a class=\"reference internal\" href=\"/ja/5.1/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> を作る必要があります。</p>\n<p>オブジェクトを取得するために、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.list.ListView\" title=\"django.views.generic.list.ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin\" title=\"django.views.generic.list.MultipleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">MultipleObjectMixin</span></code></a> を使用します。このミックスインは、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_queryset\" title=\"django.views.generic.list.MultipleObjectMixin.get_queryset\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.paginate_queryset\" title=\"django.views.generic.list.MultipleObjectMixin.paginate_queryset\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">paginate_queryset()</span></code></a> の両方を提供します。 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> とは異なり、URL の一部をキーにしてクエリセットを特定する必要はありません。そのため、デフォルトではビュークラスの <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.queryset\" title=\"django.views.generic.list.MultipleObjectMixin.queryset\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">queryset</span></code></a> または <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.model\" title=\"django.views.generic.list.MultipleObjectMixin.model\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">model</span></code></a> 属性が使用されます。ここで <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_queryset\" title=\"django.views.generic.list.MultipleObjectMixin.get_queryset\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code></a> をオーバーライドする一般的な理由は、現在のユーザーに依存するなど、オブジェクトを動的に変化させることで、ブログの場合は将来の投稿を除外することなどが理由となるでしょう。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin\" title=\"django.views.generic.list.MultipleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">MultipleObjectMixin</span></code></a> も <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.ContextMixin.get_context_data\" title=\"django.views.generic.base.ContextMixin.get_context_data\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code></a> をオーバーライドして、ページ分割に適切なコンテキスト変数を含めます(ページ分割が無効な場合はダミーを提供します)。これは <code class=\"docutils literal notranslate\"><span class=\"pre\">object_list</span></code> がキーワード引数として渡される動作に依存しており、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#ListView\" title=\"ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> がそれを調整します。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a> を作成するために、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#ListView\" title=\"ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectTemplateResponseMixin\" title=\"django.views.generic.list.MultipleObjectTemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">MultipleObjectTemplateResponseMixin</span></code></a> を使用します。上記の <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectTemplateResponseMixin\" title=\"django.views.generic.detail.SingleObjectTemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectTemplateResponseMixin</span></code></a> と同様に、これは <code class=\"docutils literal notranslate\"><span class=\"pre\">get_template_names()</span></code> をオーバーライドして、<a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectTemplateResponseMixin\" title=\"django.views.generic.list.MultipleObjectTemplateResponseMixin\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">さまざまなオプション</span></code></a> を提供します。最もよく使われるのは <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;app_label&gt;/&lt;model_name&gt;_list.html</span></code> で、<code class=\"docutils literal notranslate\"><span class=\"pre\">_list</span></code> の部分は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectTemplateResponseMixin.template_name_suffix\" title=\"django.views.generic.list.MultipleObjectTemplateResponseMixin.template_name_suffix\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name_suffix</span></code></a> 属性から取得されます。（日付ベースのジェネリックビューでは、 <code class=\"docutils literal notranslate\"><span class=\"pre\">_archive</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">_archive_year</span></code> などの接尾辞を使用して、様々な用途に特化した日付ベースのリストビューで、異なるテンプレートを使用します）</p>\n</section>\n</section>\n<section id=\"using-django-s-class-based-view-mixins\">\n<h2>Django のクラスベースのビューのミックスイン (mixin) を使用する<a class=\"heading-anchor\" href=\"#using-django-s-class-based-view-mixins\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django のクラスベースのジェネリックビューが、提供されたミックスインをどのように使うか見てきたので、それらを組み合わせる他の方法を見てみましょう。組み込みのクラスベースのビューや、他のクラスベースのジェネリックビューと組み合わせることに変わりはありませんが、Django を「箱から出してすぐに」使えるものよりも、もっとレアな問題をカバーしています。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>すべてのミックスインを一緒に使用することができるわけではなく、すべてのクラスベースのジェネリックビューをすべての他のミックスインと一緒に使用することもできません。ここではいくつかの動作する例を紹介します。他の機能を組み合わせる場合は、使用するさまざまなクラス間で重複する属性やメソッドの相互作用、および <a class=\"reference external\" href=\"https://www.python.org/download/releases/2.3/mro/\">method resolution order</a> （メソッド解決順序: MRO）が、どのバージョンのメソッドがどんな順番で呼び出されるかに影響することを考慮する必要があります。</p>\n<p>Django の <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/\"><span class=\"doc\">クラスベースビュー</span></a> および <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins/\"><span class=\"doc\">クラスベースビュー ミックスイン</span></a> のリファレンスドキュメントは、異なるクラスやミックスイン間でよく競合を引き起こす属性やメソッドを理解するのに役立ちます。</p>\n<p>もし迷ったら、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#View\" title=\"View\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">View</span></code></a> や <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#TemplateView\" title=\"TemplateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateView</span></code></a> をベースにして、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> や <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin\" title=\"django.views.generic.list.MultipleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">MultipleObjectMixin</span></code></a> を使うのが良いでしょう。おそらく、より多くのコードを書くことになるでしょうが、後でそのコードに辿り着いた他の誰かが明確に理解できる可能性が高くなります。(もちろん、Django のクラスベースのジェネリックビューの実装を見て、問題への取り組み方のヒントを得ることもできます)。</p>\n</aside>\n<section id=\"using-singleobjectmixin-with-view\">\n<h3>ビューで <code class=\"docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code> を使用する<a class=\"heading-anchor\" href=\"#using-singleobjectmixin-with-view\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>もし <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> にのみ反応するクラスベースのビューを書きたいのであれば、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/base/#django.views.generic.base.View\" title=\"django.views.generic.base.View\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">View</span></code></a> をサブクラス化し、その中に <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> メソッドを書きます。しかし、URLから特定したオブジェクトに対して処理を行いたい場合、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> が提供する機能が必要になります。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.1/topics/class-based-views/generic-display/\"><span class=\"doc\">クラスベースのジェネリックビューのイントロダクション</span></a> で使用した <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> モデルを使って、このデモンストレーションを行います。</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">views.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponseForbidden</span><span class=\"p\">,</span> <span class=\"n\">HttpResponseRedirect</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">reverse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">View</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic.detail</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SingleObjectMixin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Author</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">RecordInterestView</span><span class=\"p\">(</span><span class=\"n\">SingleObjectMixin</span><span class=\"p\">,</span> <span class=\"n\">View</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;Records the current user&#39;s interest in an author.&quot;&quot;&quot;</span>\n\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Author</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">post</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_authenticated</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">HttpResponseForbidden</span><span class=\"p\">()</span>\n\n        <span class=\"c1\"># Look up the author we&#39;re interested in.</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_object</span><span class=\"p\">()</span>\n        <span class=\"c1\"># Actually record interest somehow here!</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">HttpResponseRedirect</span><span class=\"p\">(</span>\n            <span class=\"n\">reverse</span><span class=\"p\">(</span><span class=\"s2\">&quot;author-detail&quot;</span><span class=\"p\">,</span> <span class=\"n\">kwargs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span><span class=\"o\">.</span><span class=\"n\">pk</span><span class=\"p\">})</span>\n        <span class=\"p\">)</span>\n</code></pre></figure>\n<p>実際には、リレーショナルデータベースではなく、キーバリューストアに関心事を記録したいと思うでしょう。その部分は省略しました。 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> を使用するビューで興味があるのは作者を調べるところだけで、これは <code class=\"docutils literal notranslate\"><span class=\"pre\">self.get_object()</span></code> を呼び出すことで行います。それ以外は全てミックスインが行ってくれます。</p>\n<p>これをURLにフックするのは簡単です:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">urls.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">RecordInterestView</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span>\n        <span class=\"s2\">&quot;author/&lt;int:pk&gt;/interest/&quot;</span><span class=\"p\">,</span>\n        <span class=\"n\">RecordInterestView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">(),</span>\n        <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;author-interest&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code> という名前のグループに注目してください。 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_object\" title=\"django.views.generic.detail.SingleObjectMixin.get_object\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_object()</span></code></a> は <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> のインスタンスを検索するために使用します。スラグを使うこともできますし、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> の他の機能を使うこともできます。</p>\n</section>\n<section id=\"using-singleobjectmixin-with-listview\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">ListView</span></code> で <code class=\"docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code> を使用する<a class=\"heading-anchor\" href=\"#using-singleobjectmixin-with-listview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.list.ListView\" title=\"django.views.generic.list.ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> は組み込みのページ分割を提供しますが、別のオブジェクトに(外部キーで)リンクされたオブジェクトのリストをページ分割したいかもしれません。出版の例では、特定の出版社のすべての本をページ分割したいかもしれません。</p>\n<p>これを行う1つの方法は、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#ListView\" title=\"ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> を組み合わせることで、ページ分割された本のリストのクエリセットを、見つかった出版社から単一のオブジェクトとしてぶら下げることができます。これを行うには、2つの異なるクエリセットを用意する必要があります:</p>\n<dl class=\"simple\">\n<dt><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.list.ListView\" title=\"django.views.generic.list.ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> で使用するための <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> の クエリセット</dt><dd><p>リストアップしたい本の <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> にアクセスできるので、 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> をオーバーライドして、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> の <a class=\"reference internal\" href=\"/ja/5.1/topics/db/queries/#backwards-related-objects\"><span class=\"std std-ref\">逆方向の外部キーマネージャ</span></a> を使用します。</p>\n</dd>\n<dt><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_object\" title=\"django.views.generic.detail.SingleObjectMixin.get_object\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_object()</span></code></a> で使用する <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> クエリセットです。</dt><dd><p>正しい <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> オブジェクトを取得するには、デフォルトの <code class=\"docutils literal notranslate\"><span class=\"pre\">get_object()</span></code> の実装に頼りましょう。ただし、明示的に <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code> 引数を渡さなければなりません。なぜなら、デフォルトの <code class=\"docutils literal notranslate\"><span class=\"pre\">get_object()</span></code> の実装では <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> を呼び出しますが、これは <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> の代わりに <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> オブジェクトを返すようにオーバーライドしているからです。</p>\n</dd>\n</dl>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code> については慎重に考える必要があります。 <code class=\"docutils literal notranslate\"><span class=\"pre\">context_object_name</span></code> がセットされている場合、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#ListView\" title=\"ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> の両方がその値のもとのコンテキストデータに格納されます。そのため、代わりに <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> が明示的にコンテキストデータに含まれるようにする必要があります。 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#ListView\" title=\"ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> は <code class=\"docutils literal notranslate\"><span class=\"pre\">super()</span></code> を呼び出すことを忘れなければ、適切な <code class=\"docutils literal notranslate\"><span class=\"pre\">page_obj</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">paginator</span></code> を自動で追加してくれます。</p>\n</aside>\n<p>これで新しい <code class=\"docutils literal notranslate\"><span class=\"pre\">PublisherDetailView</span></code> を書くことができます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic.detail</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SingleObjectMixin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Publisher</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherDetailView</span><span class=\"p\">(</span><span class=\"n\">SingleObjectMixin</span><span class=\"p\">,</span> <span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">paginate_by</span> <span class=\"o\">=</span> <span class=\"mi\">2</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;books/publisher_detail.html&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_object</span><span class=\"p\">(</span><span class=\"n\">queryset</span><span class=\"o\">=</span><span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">())</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_context_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_context_data</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s2\">&quot;publisher&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span>\n        <span class=\"k\">return</span> <span class=\"n\">context</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span><span class=\"o\">.</span><span class=\"n\">book_set</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> 内で <code class=\"docutils literal notranslate\"><span class=\"pre\">self.object</span></code> を設定していることに注目してください。これにより、後で <code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> で再利用できます。 <code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code> を指定しない場合、テンプレートは通常の <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#ListView\" title=\"ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> の選択肢にデフォルトで設定されます。この場合、それは <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;books/book_list.html&quot;</span></code> になります。なぜなら、これは本のリストだからです。 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#ListView\" title=\"ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> について何も知らないため、このビューが <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> と関連していることを全く理解していません。</p>\n<p>この例では <code class=\"docutils literal notranslate\"><span class=\"pre\">paginate_by</span></code> を意図的に小さくしているので、ページ分割の動作を確認するためにたくさんのブックを作成する必要はありません！以下が使いたいテンプレートです:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">extends</span> <span class=\"s2\">&quot;base.html&quot;</span> <span class=\"cp\">%}</span>\n\n<span class=\"cp\">{%</span> <span class=\"k\">block</span> <span class=\"nv\">content</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>Publisher <span class=\"cp\">{{</span> <span class=\"nv\">publisher.name</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">ol</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">book</span> <span class=\"k\">in</span> <span class=\"nv\">page_obj</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">book.title</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">ol</span><span class=\"p\">&gt;</span>\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;pagination&quot;</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">span</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;step-links&quot;</span><span class=\"p\">&gt;</span>\n            <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">page_obj.has_previous</span> <span class=\"cp\">%}</span>\n                <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;?page=</span><span class=\"cp\">{{</span> <span class=\"nv\">page_obj.previous_page_number</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>previous<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n            <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n\n            <span class=\"p\">&lt;</span><span class=\"nt\">span</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;current&quot;</span><span class=\"p\">&gt;</span>\n                Page <span class=\"cp\">{{</span> <span class=\"nv\">page_obj.number</span> <span class=\"cp\">}}</span> of <span class=\"cp\">{{</span> <span class=\"nv\">paginator.num_pages</span> <span class=\"cp\">}}</span>.\n            <span class=\"p\">&lt;/</span><span class=\"nt\">span</span><span class=\"p\">&gt;</span>\n\n            <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">page_obj.has_next</span> <span class=\"cp\">%}</span>\n                <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;?page=</span><span class=\"cp\">{{</span> <span class=\"nv\">page_obj.next_page_number</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>next<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n            <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">span</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endblock</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"avoid-anything-more-complex\">\n<h2>これより複雑なことはやめておきましょう<a class=\"heading-anchor\" href=\"#avoid-anything-more-complex\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>一般的に必要な機能は、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin\" title=\"django.views.generic.base.TemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code></a> や <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> で実現できます。上記のように、少し注意すれば、<code class=\"docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code> を <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.list.ListView\" title=\"django.views.generic.list.ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> と組み合わせることもできます。しかし、そうするとますます複雑になります。適切な判断基準は以下の通りです:</p>\n<aside class=\"admonition admonition-hint\">\n<p class=\"admonition-title\">ヒント</p>\n<p>各ビューでは、 <a class=\"reference internal\" href=\"/ja/5.1/topics/class-based-views/generic-display/\"><span class=\"doc\">detail, list</span></a>, <a class=\"reference internal\" href=\"/ja/5.1/topics/class-based-views/generic-editing/\"><span class=\"doc\">editing</span></a>, date のようなクラスベースのジェネリックビューのグループのミックスイン/ビューのうち、それぞれ1つだけを使うようにしてください。たとえば、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#TemplateView\" title=\"TemplateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateView</span></code></a> (組み込みのビュー) と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin\" title=\"django.views.generic.list.MultipleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">MultipleObjectMixin</span></code></a> (ジェネリックリスト) の組み合わせは問題ありませんが、 <code class=\"docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code> (ジェネリック詳細ビュー) と <code class=\"docutils literal notranslate\"><span class=\"pre\">MultipleObjectMixin</span></code> (ジェネリックリストビュー) の組み合わせは問題が発生しやすいでしょう。</p>\n</aside>\n<p>より洗練されたものにしようとするとどうなるかを示すために、より単純な解決策がある場合に可読性と保守性を犠牲にする例を示します。まず、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-editing/#django.views.generic.edit.FormMixin\" title=\"django.views.generic.edit.FormMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormMixin</span></code></a> を組み合わせて、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> を使ってオブジェクトを表示しているのと同じ URL に Django <a class=\"reference internal\" href=\"/ja/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> を <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> できるようにしようという素朴な試みを見てみましょう。</p>\n<section id=\"using-formmixin-with-detailview\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">DetailView</span></code> で <code class=\"docutils literal notranslate\"><span class=\"pre\">FormMixin</span></code> を使用する<a class=\"heading-anchor\" href=\"#using-formmixin-with-detailview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>先ほどの <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#View\" title=\"View\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">View</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> を一緒に使う例を思い出してください。ユーザが特定の作者に興味を持ったことを記録していました。ここで、なぜその作者が好きなのか、メッセージを残させたいとします。ここではリレーショナルデータベースではなく、より難解な方法で情報を保存することになると仮定しましょう。その詳細についてはここでは考慮しません。</p>\n<p>この時点で、ユーザのブラウザから Django に送られる情報をカプセル化する <a class=\"reference internal\" href=\"/ja/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> に手を伸ばすのは自然なことです。また、私たちは <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Representational_state_transfer\">REST</a> に重きを置いているので、ユーザからのメッセージを取得するのと同じように、作者を表示するのにも同じ URL を使いたいとします。そのために <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorDetailView</span></code> を書き換えてみましょう。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> の処理は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> から引き継ぎますが、コンテキストデータに <a class=\"reference internal\" href=\"/ja/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> を追加して、テンプレートでレンダリングできるようにします。また、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-editing/#django.views.generic.edit.FormMixin\" title=\"django.views.generic.edit.FormMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormMixin</span></code></a> からフォーム処理を取り込みます。そして、 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> 時にフォームが適切に呼び出されるようにコードを少し書きましょう。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-editing/#django.views.generic.edit.FormMixin\" title=\"django.views.generic.edit.FormMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormMixin</span></code></a> を使用し、自分で <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> を実装します。 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#FormView\" title=\"FormView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormView</span></code></a> （すでに適切な <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> を提供している）と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> は、両方のビューが <code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> を実装しているため、混在させるとより混乱する可能性があるからです。</p>\n</aside>\n<p>新しい <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorDetailView</span></code> は次のようになります:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># CAUTION: you almost certainly do not want to do this.</span>\n<span class=\"c1\"># It is provided as part of a discussion of problems you can</span>\n<span class=\"c1\"># run into when combining different generic class-based view</span>\n<span class=\"c1\"># functionality that is not designed to be used together.</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">forms</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponseForbidden</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">reverse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic.edit</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">FormMixin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Author</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorInterestForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n    <span class=\"n\">message</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorDetailView</span><span class=\"p\">(</span><span class=\"n\">FormMixin</span><span class=\"p\">,</span> <span class=\"n\">DetailView</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Author</span>\n    <span class=\"n\">form_class</span> <span class=\"o\">=</span> <span class=\"n\">AuthorInterestForm</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_success_url</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">reverse</span><span class=\"p\">(</span><span class=\"s2\">&quot;author-detail&quot;</span><span class=\"p\">,</span> <span class=\"n\">kwargs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span><span class=\"o\">.</span><span class=\"n\">pk</span><span class=\"p\">})</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">post</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_authenticated</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">HttpResponseForbidden</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_object</span><span class=\"p\">()</span>\n        <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_form</span><span class=\"p\">()</span>\n        <span class=\"k\">if</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">form_valid</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">form_invalid</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">form_valid</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">form</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Here, we would record the user&#39;s interest using the message</span>\n        <span class=\"c1\"># passed in form.cleaned_data[&#39;message&#39;]</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">form_valid</span><span class=\"p\">(</span><span class=\"n\">form</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">get_success_url()</span></code> はリダイレクト先を提供し、デフォルト実装の <code class=\"docutils literal notranslate\"><span class=\"pre\">form_valid()</span></code> で使用されます。前述のように、独自の <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> を用意する必要があります。</p>\n</section>\n<section id=\"a-better-solution\">\n<h3>より良い解決策<a class=\"heading-anchor\" href=\"#a-better-solution\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-editing/#django.views.generic.edit.FormMixin\" title=\"django.views.generic.edit.FormMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormMixin</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> の間の微妙な相互作用の数は、すでに私たちの管理能力を試しています。このようなクラスを自分で書こうとは思わないでしょう。</p>\n<p>この場合、 <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> メソッドを自分で書くことはできますが、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> を唯一の汎用機能として保持し、 <a class=\"reference internal\" href=\"/ja/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> を処理するコードを自分で書くことは多くの重複を伴います。</p>\n<p>代わりに、フォームを処理するための別々のビューを持つ方が、上記のアプローチよりも作業量が少ないでしょう。その場合、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> とは別の <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView\" title=\"django.views.generic.edit.FormView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormView</span></code></a> を使うことになるでしょう。</p>\n</section>\n<section id=\"an-alternative-better-solution\">\n<h3>もう一つのより良い解決策<a class=\"heading-anchor\" href=\"#an-alternative-better-solution\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>ここで本当にやろうとしていることは、同じURLから2つの異なるクラスベースのビューを使うことです。では、なぜそうしないのでしょうか？ここでは非常に明確な区分があります。 <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> リクエストは <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#DetailView\" title=\"DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> (コンテキストデータに <a class=\"reference internal\" href=\"/ja/5.1/ref/forms/api/#django.forms.Form\" title=\"django.forms.Form\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Form</span></code></a> を追加したもの) を取得し、 <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code> リクエストは <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#FormView\" title=\"FormView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormView</span></code></a> を取得します。まずはこれらのビューを設定しましょう。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorDetailView</span></code> ビューは、最初に紹介した <a class=\"reference internal\" href=\"/ja/5.1/topics/class-based-views/generic-display/#generic-views-extra-work\"><span class=\"std std-ref\">AuthorDetailView</span></a> とほとんど同じです。 <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorInterestForm</span></code> をテンプレートで利用できるようにするために、独自の <code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code> を書く必要があります。わかりやすくするために、先ほどの <code class=\"docutils literal notranslate\"><span class=\"pre\">get_object()</span></code> のオーバーライドは省略します:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">forms</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Author</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorInterestForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n    <span class=\"n\">message</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorDetailView</span><span class=\"p\">(</span><span class=\"n\">DetailView</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Author</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_context_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_context_data</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s2\">&quot;form&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">AuthorInterestForm</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">context</span>\n</code></pre></div>\n<p>次に <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorInterestFormView</span></code> は <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#FormView\" title=\"FormView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FormView</span></code></a> ですが、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin\" title=\"django.views.generic.detail.SingleObjectMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectMixin</span></code></a> を持ってきて、今話題にしている著者を見つけられるようにしなければなりません。また、 <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorDetailView</span></code> が <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> で使用しているのと同じテンプレートをフォームエラーでレンダリングできるように <code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code> を忘れずに指定しなければなりません:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponseForbidden</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">reverse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">FormView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic.detail</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SingleObjectMixin</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorInterestFormView</span><span class=\"p\">(</span><span class=\"n\">SingleObjectMixin</span><span class=\"p\">,</span> <span class=\"n\">FormView</span><span class=\"p\">):</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;books/author_detail.html&quot;</span>\n    <span class=\"n\">form_class</span> <span class=\"o\">=</span> <span class=\"n\">AuthorInterestForm</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Author</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">post</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_authenticated</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">HttpResponseForbidden</span><span class=\"p\">()</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_object</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">post</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_success_url</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">reverse</span><span class=\"p\">(</span><span class=\"s2\">&quot;author-detail&quot;</span><span class=\"p\">,</span> <span class=\"n\">kwargs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">object</span><span class=\"o\">.</span><span class=\"n\">pk</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>最後に、これを新しい <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorView</span></code> ビューにまとめます。クラスベースのビューで <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/base/#django.views.generic.base.View.as_view\" title=\"django.views.generic.base.View.as_view\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_view()</span></code></a> を呼び出すと、関数ベースのビューと全く同じように動作するものが得られることは既に知っています。そのため、2つのサブビューのどちらかを選択する時点でこれを行うことができます。</p>\n<p>キーワード引数を <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/base/#django.views.generic.base.View.as_view\" title=\"django.views.generic.base.View.as_view\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_view()</span></code></a> に渡すには、 URLconf と同じようにします。例えば、 <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthorInterestFormView</span></code> の動作を別の URL にも表示させたいが、別のテンプレートを使いたい場合などです:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">View</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorView</span><span class=\"p\">(</span><span class=\"n\">View</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"n\">view</span> <span class=\"o\">=</span> <span class=\"n\">AuthorDetailView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">post</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"n\">view</span> <span class=\"o\">=</span> <span class=\"n\">AuthorInterestFormView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>この方法は、他のクラスベースのジェネリックビューや、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#View\" title=\"View\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">View</span></code></a> や <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/flattened-index/#TemplateView\" title=\"TemplateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateView</span></code></a> を直接継承した独自のクラスベースのビューでも使用できます。異なるビューを可能な限り分離した状態に保つことができるからです。</p>\n</section>\n</section>\n<section id=\"more-than-just-html\">\n<span id=\"jsonresponsemixin-example\"></span><h2>単純な HTML を超える<a class=\"heading-anchor\" href=\"#more-than-just-html\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>クラスベースビューが役に立つのは、同じことを何度もしたい場合です。たとえば API を作成している場合、全てのビューはレンダリングされた HTML ではなく JSON を返す必要があります。</p>\n<p>全てのビューで利用するために、 JSONへの変換処理をするmixinクラスを作成できます。</p>\n<p>たとえば、JSONのmixinは以下のようになるでしょう。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">JsonResponse</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">JSONResponseMixin</span><span class=\"p\">:</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    A mixin that can be used to render a JSON response.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render_to_json_response</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">response_kwargs</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Returns a JSON response, transforming &#39;context&#39; to make the payload.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"n\">JsonResponse</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_data</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">),</span> <span class=\"o\">**</span><span class=\"n\">response_kwargs</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Returns an object that will be serialized as JSON by json.dumps().</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># Note: This is *EXTREMELY* naive; in reality, you&#39;ll need</span>\n        <span class=\"c1\"># to do much more complex handling to ensure that arbitrary</span>\n        <span class=\"c1\"># objects -- such as Django model instances or querysets</span>\n        <span class=\"c1\"># -- can be serialized as JSON.</span>\n        <span class=\"k\">return</span> <span class=\"n\">context</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>Djangoモデルやクエリセットを正しくJSONに変換する方法についての詳細は <a class=\"reference internal\" href=\"/ja/5.1/topics/serialization/\"><span class=\"doc\">Django オブジェクトのシリアライズ</span></a> ドキュメントを参照してください。</p>\n</aside>\n<p>このmixinは <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.render_to_response\" title=\"django.views.generic.base.TemplateResponseMixin.render_to_response\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code></a> と同じ引数をもつ <code class=\"docutils literal notranslate\"><span class=\"pre\">render_to_json_response()</span></code> メソッドを提供します。これを使用するには、たとえば <code class=\"docutils literal notranslate\"><span class=\"pre\">TemplateVIew</span></code> へ取り入れ、 <code class=\"docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code> をオーバーライドして代わりに <code class=\"docutils literal notranslate\"><span class=\"pre\">render_to_json_response()</span></code> を呼び出す必要があります。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">TemplateView</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">JSONView</span><span class=\"p\">(</span><span class=\"n\">JSONResponseMixin</span><span class=\"p\">,</span> <span class=\"n\">TemplateView</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render_to_response</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">response_kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">render_to_json_response</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">response_kwargs</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>同様に、このミックスインをジェネリックビューで使用することもできます。 <code class=\"docutils literal notranslate\"><span class=\"pre\">JSONResponseMixin</span></code> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.BaseDetailView\" title=\"django.views.generic.detail.BaseDetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseDetailView</span></code></a> (テンプレートレンダリングの動作が混ざる前の <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a>) をミックスインすることで、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> の独自のバージョンを作ることができます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic.detail</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseDetailView</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">JSONDetailView</span><span class=\"p\">(</span><span class=\"n\">JSONResponseMixin</span><span class=\"p\">,</span> <span class=\"n\">BaseDetailView</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render_to_response</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">response_kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">render_to_json_response</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">response_kwargs</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>このビューはレスポンスの作成を除いて、他の <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> と同じように記述され、同じように動作します。</p>\n<p>本当に冒険をしたいのであれば、クエリ引数や HTTP ヘッダなどの HTTP リクエストのプロパティに応じて、HTML と JSON の <em>両方</em> のコンテンツを返すことができる <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a> サブクラスを混ぜることもできます。 <code class=\"docutils literal notranslate\"><span class=\"pre\">JSONResponseMixin</span></code> と <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectTemplateResponseMixin\" title=\"django.views.generic.detail.SingleObjectTemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SingleObjectTemplateResponseMixin</span></code></a> の両方をミックスインして、 <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.render_to_response\" title=\"django.views.generic.base.TemplateResponseMixin.render_to_response\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code></a> の実装をオーバーライドし、ユーザが要求したレスポンスの種類に応じて適切なレンダリングメソッドに振り分けます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic.detail</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SingleObjectTemplateResponseMixin</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">HybridDetailView</span><span class=\"p\">(</span>\n    <span class=\"n\">JSONResponseMixin</span><span class=\"p\">,</span> <span class=\"n\">SingleObjectTemplateResponseMixin</span><span class=\"p\">,</span> <span class=\"n\">BaseDetailView</span>\n<span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render_to_response</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Look for a &#39;format=json&#39; GET argument</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">GET</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s2\">&quot;format&quot;</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;json&quot;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">render_to_json_response</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">render_to_response</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Pythonのメソッド多重定義に関する仕様により、 <code class=\"docutils literal notranslate\"><span class=\"pre\">super().render_to_response(context)</span></code> の呼び出しは <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin\" title=\"django.views.generic.base.TemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code></a> に実装された <a class=\"reference internal\" href=\"/ja/5.1/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.render_to_response\" title=\"django.views.generic.base.TemplateResponseMixin.render_to_response\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code></a> メソッドを呼び出します。</p>\n</section>","rootId":"using-mixins-with-class-based-views","toc":[{"title":"コンテキストとテンプレートのレスポンス","anchor":"context-and-template-responses","children":[]},{"title":"Django の一般的なクラスベースのビューを構築する","anchor":"building-up-django-s-generic-class-based-views","children":[{"title":"DetailView: Django の1つのオブジェクトを対象とするビュー","anchor":"detailview-working-with-a-single-django-object","children":[]},{"title":"ListView: Django の複数のオブジェクトを対象とするビュー","anchor":"listview-working-with-many-django-objects","children":[]}]},{"title":"Django のクラスベースのビューのミックスイン (mixin) を使用する","anchor":"using-django-s-class-based-view-mixins","children":[{"title":"ビューで SingleObjectMixin を使用する","anchor":"using-singleobjectmixin-with-view","children":[]},{"title":"ListView で SingleObjectMixin を使用する","anchor":"using-singleobjectmixin-with-listview","children":[]}]},{"title":"これより複雑なことはやめておきましょう","anchor":"avoid-anything-more-complex","children":[{"title":"DetailView で FormMixin を使用する","anchor":"using-formmixin-with-detailview","children":[]},{"title":"より良い解決策","anchor":"a-better-solution","children":[]},{"title":"もう一つのより良い解決策","anchor":"an-alternative-better-solution","children":[]}]},{"title":"単純な HTML を超える","anchor":"more-than-just-html","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/5.1/topics/"},{"docname":"topics/class-based-views/index","title":"クラスベースビュー","url":"/ja/5.1/topics/class-based-views/"}],"prev":{"docname":"topics/class-based-views/generic-editing","title":"クラスベースのビューでフォームを扱う","url":"/ja/5.1/topics/class-based-views/generic-editing/"},"next":{"docname":"topics/migrations","title":"マイグレーション","url":"/ja/5.1/topics/migrations/"},"formats":{"html":"/ja/5.1/topics/class-based-views/mixins/","markdown":"/ja/5.1/topics/class-based-views/mixins.md","json":"/ja/5.1/topics/class-based-views/mixins.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/topics/class-based-views/mixins.txt","official":"https://docs.djangoproject.com/ja/5.1/topics/class-based-views/mixins/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}