ユーニックス総合研究所

  • home
  • archives
  • django-detail-view

DjangoのDetailViewのかしこい使い方【Python】

  • 作成日: 2020-12-10
  • 更新日: 2023-12-26
  • カテゴリ: Django

DetailViewの使い方

PythonのWebフレームワークであるDjango(ジャンゴ)には開発者の負担を減らすためのモジュールが多数あります。
DetailView(ディティール・ビュー)はその中の1つです。

DetailViewを使うことでオブジェクトの個別ページの開発コストを減らすことが可能です。
この記事ではDetailViewについて具体的に↓を見ていきます。

  • DetailViewの概要
  • モデルの作成
  • オブジェクトの作成
  • DetailVeiwによるビューの作成
  • その他のDetailViewの機能

前提

今回はアプリケーションであるmyappというアプリを作成しておきます。
python manage.py startappなどでこのアプリを作成してある想定です。

DetailViewの概要

DetailViewは個別のオブジェクトを表示するためのビューで、クラスです。
DetailViewはdjango.views.genericで定義されています。
そのためDetailViewを使う場合はdjango.views.genericからDetailViewクラスをインポートします。

ビューを作るには、DetailViewクラスを継承したクラスを作ります。
そしてそのクラスにモデルを設定すると、クラスはそのモデルを使ってオブジェクトを取得します。
そしてクラスはそのオブジェクトをテンプレートファイルに渡します。

DetailViewの設定で必須なのはこのモデルの設定だけで、あとは自動でセットアップされます。
詳細に設定したい場合はクラスの属性やメソッドを定義することで可能になっています。

DetailViewはただのビューなので、このビューを使うにはurls.pyの編集やモデルの作成、それからテンプレートファイルの作成が必要になります。
またDetailViewの他にもdjango.views.genericにはいろいろなビューが置かれています。

モデルの作成

今回の解説用にモデルを作ります。
モデルは人物を表現するモデルです。
このモデルには名前を表すnameフィールドや年齢を表すageフィールドを作っておきます。

from django.db import models  


class Person(models.Model):  
    name = models.CharField(max_length=128)  
    age = models.IntegerField()  

このモデルをDetailViewに渡すことでビューが機能するようになります。

オブジェクトの作成

モデルを作成したらDjangoのシェルを使ってデータベースにオブジェクトを作成します。
↓のようにDjangoのシェルを起動します。

python manage.py shell  

そして↓のコードを実行し、オブジェクトを作成します。

from myapp.models import Person  

Person.objects.create(name='Taro', age=20)  
Person.objects.create(name='Hanako', age=18)  
Person.objects.create(name='Kenji', age=28)  

DetailVeiwによるビューの作成

ではDetailViewでビューを作成します。
アプリケーションのviews.pyを↓のように編集します。

from django.views.generic import DetailView  
from .models import Person  


class PersonDetail(DetailView):  
    model = Person   

ひとつずつ見ていきます。
まず↓のようにDetailViewdjango.views.genericからインポートします。

from django.views.generic import DetailView  

そして↓のように先ほど作成したPersonモデルもインポートします。

from .models import Person  

↓のようにPersonDetailというクラスを作成します。
このクラスはDetailViewクラスを継承するようにします。
そしてクラスの属性modelPersonモデルをセットします。

class PersonDetail(DetailView):  
    model = Person   

ビューの作成はこれだけでOKです。あとは自動でやってくれます。

🦝 < かんたん!

urls.pyの編集

プロジェクトのurls.pyを↓のように編集します。

from django.contrib import admin  
from django.urls import path  
from myapp import views  

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('persons/detail/<int:pk>/', views.PersonDetail.as_view()),  
]  

今回はpersons/detail/<int:pk>/にビューをセットします。
<int:pk>はオブジェクトのIDが指定されます。

DetailViewを継承したクラスはas_view()というメソッドが使えます。
このメソッドを使うとpath()に設定可能なビューを取得することが出来ます。

テンプレートファイルの作成

DetailViewはデフォルトでは「アプリ名/ビュー名.html」のテンプレートファイルを参照します。
さきほどPersonDetailというビューを作りましたが、このビューの場合はビュー名がPersonDetailでアプリ名がmyappなので、テンプレートファイルは「myapp/person_detail.html」になります。
これはmyapp/templates/myapp/person_detail.htmlのことです。

このテンプレートファイルを↓のような内容で作成します。

<p>Name: {{ object.name }}, Age: {{ object.age }}</p>  

DetailViewはデフォルトで取得したオブジェクトをobjectという変数名でコンテキストに保存します。
そのため↑のようにobjectを参照することでオブジェクトにアクセスすることができます。
↑の例ではPersonオブジェクトのnameageフィールドを参照しています。

ビューとurls.pyとテンプレートファイルを作ったので開発用サーバーを起動し、/persons/detail/1/にアクセスします。
すると↓のような画面が表示されます。

その他のDetailViewの機能

DetailViewには他にも↓のような機能があります。

コンテキスト内の変数を別の名前に変更する

テンプレートファイルでobjectという変数を参照していましたが、このobjectという変数名を変更したい場合があります。
そういう時は↓のようにビューのcontext_object_name属性に名前を設定することで変更が可能です。

from django.views.generic import DetailView  
from .models import Person  


class PersonDetail(DetailView):  
    model = Person   
    context_object_name = 'person'  

↑のようにcontext_object_namepersonという文字列を設定しました。
これでテンプレートファイル内ではpersonという変数名でオブジェクトを参照することが出来ます。

<p>Name: {{ person.name }}, Age: {{ person.age }}</p>  

コンテキストを動的に取得し設定する

ビューの取得しているコンテキストを編集したい場合があります。
そういう時は↓のようにget_context_data()メソッドを定義(オーバーライド)します。
↓はコンテキストにmessageという変数を作っているところです。

from django.views.generic import DetailView  
from .models import Person  


class PersonDetail(DetailView):  
    model = Person   

    def get_context_data(self, **kwargs):  
        context = super().get_context_data(**kwargs)  
        context['message'] = 'Hello, World!'  
        return context  

get_context_data()内で親のget_context_data()を呼び出すと、コンテキストを取得することが出来ます。
そのコンテキストにデータを設定し、returnでコンテキストを返せば、テンプレートファイルに渡すコンテキストを編集することが出来ます。

<p>{{ message }}</p>  
<p>Name: {{ person.name }}, Age: {{ person.age }}</p>  

テンプレートファイル名を変更する

DetailViewの参照するテンプレートファイルのパスを変更したい場合はクラスの属性template_nameにパスを設定します。

from django.views.generic import DetailView  
from .models import Person  


class PersonDetail(DetailView):  
    model = Person   
    template_name = 'myapp/my_detail.html'  

↑の場合、PersonDetailビューはmyapp/my_detail.htmlを参照するようになります。

おわりに

DetailViewを使えば個別のオブジェクトの表示の手間を減らすことが出来ます。
活用すれば開発が楽になるかもしれません。

🦝 < オブジェクトの詳細をちょうだい

🐭 < 韻を踏んでらっしゃる

関連記事

参考