6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonその3Advent Calendar 2019

Day 13

TemplateViewをつかってみよう!Detailview編

Last updated at Posted at 2019-12-10

#今回使用するのはDetailView

目標はListViewで表示されるデータの詳細を見れるようにすることです。
前回のIndexView作成チュートリアルの続きの内容になります。

超絶シンプルに書いており、djangoに慣れようという目的が強いため、手を動かしてDetailViewに慣れたいといった方向けに記事を書いています。

また、初めからTemplateViewを練習したい方は初めのIndexView作成チュートリアルからご覧になると、確実に作成ができます。

##ファイル構成

mysite
│  db.sqlite3
│  manage.py
├─mysite
│  │  settings.py
│  │  urls.py
└─test_app
    │  admin.py
    │  apps.py
    │  models.py
    │  tests.py
    │  urls.py(ここをルーティング設定のために編集)
    │  views.py(ここをDetailView設定のために編集)
    ├─migrations
    └─templates
       └─test_app
            └─list.html(ここを詳細ページに飛ぶために編集)
               detail.html(ここをページ表示のために編集)

##前回作成したShopモデルを使用します。
使用するモデル名はShopです。
nameは30文字制限の文字列フィールド、
tell_numは13文字制限の文字列フィールド、
addressは30文字制限の文字列フィールド、
created_atは作成日と時間が初期値に設定される日時フィールドを定義しています。

models.py
from django.db import models

# Create your models here.
class Shop(models.Model):
    #各フィールドの定義
    name = models.CharField('shopname',max_length=30)
    tell_num = models.CharField('tell_number',max_length=13)
    address = models.CharField('address',max_length=30)
    created_at = models.DateTimeField(auto_now_add=True)

    #admin画面の表示内容
    def __str__(self):
        return self.name

##数字で詳細を表示するためにルーティングを設定する
ここではhttp://local:8000/1/など、数字を入れるだけで紐づく詳細ページにアクセスできるように設定します。
このようなpathを書いてあげます。

urls.py
from django.urls import path
from . import views

app_name = 'test_app'
urlpatterns = [
    path('index/',views.IndexView.as_view(),name='index'),
    path('<int:pk>/',views.DetailView.as_view(),name='detail'),
]

int型のpkという数字が入るところを用意します。views.pyDetailViewas_view()でビューとして設定しています。パスの名前はdetailとし、htmlファイルからurlを指定する場合はdetailと指定できるようにします。わかりやすいnameにしてあげると使いやすいですね。

##views.pyでDetailViewを設定

views.py
from django.views import generic
from .models import Shop

class IndexView(generic.ListView):
    model = Shop
    template_name = 'test_app/list.html'

#ここを追加
class DetailView(generic.DetailView):
    model=Shop
    template_name = 'test_app/detail.view'

djangoで用意されているgenericライブラリの中のDetailViewを継承しています。
モデルとテンプレートの指定のみで設定完了です。

##detail.htmlで詳細ページを作成
templates/test_app/detail.htmlを新たに作成します。
ファイル名はビューファイルでtemplate_nameとして指定されています。

detail.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
  <p>{{ shop.name }}の詳細</p>
  <table>
    <tr>
      <th>店名</th>
      <th>電話番号</th>
      <th>住所</th>
      <th>ページ作成日</th>
    </tr>

    <tr>
      <td>{{ shop.name }}</td>
      <td>{{ shop.tell_num  }}</td>
      <td>{{ shop.address  }}</td>
      <td>{{ shop.created_at }}</td>
    </tr>
  </table>
  </body>
</html>

shop.といった形式でモデルで定義した項目を{{ }}でくくり指定すると、html側で表示がなされます。
DetailViewを用いるとモデル名にそって先頭が小文字となったものを指定できます。
自動でこれまた設定してくれているので、モデルデータの指定が楽です!
例えば、モデル名をShopとすると、shop.と指定することになります。Carだとcarですね!

##リスト表示のindexページに詳細リンクを張ります。
このファイルでShopモデルのデータを表形式で表示しています。

list.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
  <p>一覧の表示</p>
  <table>
    <tr>
    </tr>

    {% for shop in shop_list %}
    <tr>
      <td>{{ shop.name }}</td>
      <td><a href="{% url 'test_app:detail' shop.pk %}">詳細</a></td>
    </tr>
    {% endfor %}
  </table>
  </body>
</html>
<a href="{% url 'test_app:detail' shop.pk %}">詳細</a>

が難しいのですが、htmlのaグで、リンク先をurls.pyのapp_nameで指定したtest_appnamedetailであるpathと、shoppkとあわせて記述されています。
ここではshop.idとしてもかまいません。

これで、詳細をクリックできるリンクが作成できました。
##ページの動作確認
サーバーを起動し

$python manage.py runserver

indexページを指定すると

http://localhost:8000/index

detail_list.png

そこで、詳細をクリックすると。

http://localhost:8000/1

detail.png

完成です!

##うまく動かない方へ「error:Generic detail view DetailView must be called with either an object pk or a slug in the URLconf.」
Generic detail view DetailView must be called with either an object pk or a slug in the URLconf.が出てしまう場合、pkをurls.pyに用いないといけませんので、注意しましょう。<int:pk>pk以外受け付けません。
ビューを呼び出す場合、pkという変数名の決まりでモデル指定中のShopモデルから該当オブジェクトを呼び出すのです。例えば、タピオカ屋をクリックすると、データのprimary keyが1のデータの詳細がdetai.htmlのルールに沿って表示がなされます。

#最後に
このように、テンプレートビューであるDetailビューなどを用いる場合、ルールがとても多いため混乱する恐れが高いです。💦
指定されたように書かないと動かないことが多いため、サンプルを見てたくさん書いてみると、書き方に慣れてきます。
やはり、自分で好みのサイトを全く同じでもいいので作ってみると勉強になりますよ!

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?