この記事では、クラスベースビューのリストビュー(ListView), ディテイルビュー(DetailView)の利用方法について記述する。
ListView, DetailViewの基本的な使い方
1.ListViewを用いた画面表示
ListViewのは、一覧画面など複数のデータを並べたい場合に利用される。
一般的に、DBからデータを取り出して一覧表示するが、
DBのテーブル定義を記述するmodels.pyは以下のようにした。
Studentクラスのmodels.ForeignKey(School, related_name='students')とは、Schoolクラスへの外部キーでありスクールからアクセスする場合はstudentsという名前を用いるという意味である。
- models.py
class School(models.Model):
name = models.CharField(max_length=256)
principal = models.CharField(max_length=256)
location = models.CharField(max_length=256)
def __str__(self):
return self.name
class Student(models.Model):
name = models.CharField(max_length=256)
age = models.PositiveIntegerField()
school = models.ForeignKey(School, related_name='students', on_delete='CASCADE')
# schoolへのforeign key
def __str__(self):
return self.name
次に、views.pyの設定を行う。
views.py内にListViewを継承したクラスを作成してmodelを設定する。
(このmodelがリスト表示するモデルである)
- views.py
from . import models
class SchoolListView(ListView):
# context_object_name = 'schools'
# context_object_nameはテンプレートで表示する際のモデルの参照名。これを設定で変えることができる。デフォルト(設定しない場合)では、モデル名_listである。(今回はコメントアウトした)
model = models.School
# modelの設定、この場合Schoolをリスト表示する
# template_name = 'basic_app/school_list2.html'
# template_nameはテンプレートのパスです。デフォルト(設定しない場合)では、views.pyと同じフォルダ/templates/アプリ名/モデル名_list.htmlです。
# template_name = 'basic_app/school_list2.htmlとすると、./templates/basic_app/school_list2.html (今回はコメントアウトした)
- urls.pyは以下のように記述する(クラス名.as_view())。
from basic_app import views
app_name = 'basic_app'
urlpatterns = [
path('', views.SchoolListView.as_view(), name='list'),
]
テンプレートファイルには以下のように記述した。
- school_list.html(./templates/basic_app/school_list.html)
{% block body_block %}
<h1>Welcome to a list of all schools</h1>
<ol>
{% for school in school_list %}
<!-- modelはschoolのため、modelのリストはschool_list(model名_list) (views.pyのcontext_object_nameで設定変更できる)-->
<h2><li><a href="{{ school.id }}">{{ school.name }}</a></li></h2>
<!-- aタブにschoolのidをhrefで指定することで、DetailViewに遷移できる -->
{% endfor %}
</ol>
{% endblock %}
Djangoを立ち上げて画面を表示すると以下のように表示される。
(model内に、First School, Second Schoolを入れた状態)
2.DetailViewを用いた値の表示
ListViewで画面表示をしたので、次にListViewからDetailViewへ遷移してみよう。
まず、views.pyはDetailViewを継承して以下のように記述する
- views.py
from . import models
class SchoolDetailView(DetailView):
# context_object_name = 'school'
# context_object_nameはテンプレートでのモデルの参照名、デフォルトでは"モデル名"
model = models.School
# model = としてモデルを設定する
# template_name = 'basic_app/school_detail.html'
# template_nameはテンプレートの配置先。デフォルトでは、./templates/アプリ名/モデル名_detail.html
urls.pyは以下のように<int:pk>としてpkで値を取得できるようにする。
- urls.py
from basic_app import views
app_name = 'basic_app'
urlpatterns = [
path('', views.School2ListView.as_view(), name='list'),
path('<int:pk>', views.SchoolDetailView.as_view(), name='detail')
# pathに<int:pk>として、urlがbasic_app/<int:pk>のときにSchoolDetailViewから指定したpkの値を取得できる
]
- index.html
{% block body_block %}
<div class="jumbotron">
<h1>Welcome to school detail page</h1>
<h2>details</h2>
<p>Name: {{ school.name }}</p>
<p>Principal: {{ school.principal }}</p>
<p>Location: {{ school.location }}</p>
<!-- モデル名.モデルの要素とすると、モデルの値を取得できる。-->
<h3>Students</h3>
{% for student in school.students.all %}
<!-- models.pyでforeignKeyのrelated_name=studentsとしたため、student.allとすると関連するstudentを取得できる -->
<p>{{ student.name }} {{ student.age }} yesar old</p>
{% endfor %}
</div>
{% endblock %}
Djangoを動かして、アクセスすると以下のような画面になる