質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2378閲覧

Djangoで各オブジェクトに格納されている値を確認したい(=デバッグしたい)

fukazume

総合スコア78

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/09/26 08:27

編集2020/09/26 10:41

##■質問
以下、app名/templates/diary_list.htmlというテンプレートの{% for diary in diary_list %}という記述の、diary_listという変数にどんな値が入っているのか確認する方法(=デバッグ方法)やヒントを教えていただけますでしょうか。

正しいデバッグ方法も知らない素人ですが、説明不足な点などは適宜追記して参りますので、どうぞよろしくお願い申し上げます。

template

1<!-- diary/templates/diary_list.html--> 2 3{% for diary in diary_list %} 4 <div class="post-preview"> 5 <a href="{% url 'diary:diary_detail' diary.pk %}"> 6 <h2 class="post-title"> 7 {{ diary.title }} 8 </h2> 9 <h3 class="post-subtitle"> 10 {{ diary.content|truncatechars:20 }} 11 </h3> 12 </a> 13 <p class="post-meta">{{ diary.created_at }}</p> 14 </div> 15 <hr> 16 {% empty %} 17 <p>日記がありません</p> 18{% endfor %}

##■やってみたこと
試しにmanage.py runserverでDjangoを起動中にpython manage.py shellコマンドでprint(diary_list)してみましたが未定義エラーが出ます。

pythonshell

1>>> print(diary_list) 2Traceback (most recent call last): 3 File "<console>", line 1, in <module> 4NameError: name 'diary_list' is not defined

#####きっかけ
以下の構成で、なぜviews.pyでcontextも指定されていないのにtemplateのdiary_list変数でDiaryモデルのリストオブジェクトが取得できるのか、わかりませんでしたので、まずはdiary_list変数に格納されている値をprintでシンプルに表示したいと考えました。

urls

1# diary/urls.py 2 3(略) 4 5app_name = 'diary' 6urlpatterns = [ 7(略) 8 path('diary-list/', views.DiaryListView.as_view(), name="diary_list"), 9(略) 10]

views

1# diary/views.py 2 3(略) 4class DiaryListView(LoginRequiredMixin, generic.ListView): 5 model = Diary 6 template_name = 'diary_list.html' 7(略)

models

1# diary/models.py 2 3class Diary(models.Model): 4 user = models.ForeignKey(CustomUser, verbose_name='ユーザー', on_delete=models.PROTECT) 5 title = models.CharField(verbose_name='タイトル', max_length=40) 6 content = models.TextField(verbose_name='本文', blank=True, null=True) 7 photo1 = models.ImageField(verbose_name='写真1', blank=True, null=True) 8 photo2 = models.ImageField(verbose_name='写真2', blank=True, null=True) 9 photo3 = models.ImageField(verbose_name='写真3', blank=True, null=True) 10 created_at = models.DateTimeField(verbose_name='作成日時', auto_now_add=True) 11 updated_at = models.DateTimeField(verbose_name='更新日時', auto_now=True) 12 13 class Meta: 14 verbose_name_plural = 'Diary' 15 16 def __str__(self): 17 return self.title

#####参考: 現状での私の認識

  • urls.pyでdiary_listというname属性が定義され、DiaryListViewというビューと、diary-list/というURLが、そのname属性に紐付けられている
  • print(diary_list)をエラーなく実行できれば、おそらくdiary_listに格納されたリストオブジェクトが返ってくると想像
  • diary_list変数でDiaryモデルを参照できる理由がよくわからない(DiaryListViewの中で、Diaryモデルがmodel変数に設定されて、間接的にdiary_list変数 - DiaryListView - Diaryテーブルという構造で結びついているから?)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

本題: リクエスト処理のデバッグ

Djangoにはdjango shellなどに使えるClientクラスが存在します。
django-shell実行中にこれを使って中で定義したURLにリクエストを行うことで、
通常のレスポンスコンテンツだけでなくテンプレートに渡す内容などの確認も出来ます。

python

1>>> from django.test import Client 2>>> from django.urls import reverse 3>>> client = Client() 4>>> response = client.get(reverse("diary:diary_list")) 5>>> response.context["diary_list"]

Djangoドキュメントのチュートリアルにはviewsのテストについてのセクションもあるので、読んでみるとよいかと思います。

なお、shell上での動作確認だけだと、コードの修正確認が手間になるので、ある程度したら挙動確認用にテストコードを書く方法をお勧めします。
※チュートリアルにはテストの書き方や実行のガイドが載っています

補題: DiaryListView(modelを利用するクラスview)はどのようにしてテンプレート変数を決めているか

DjangoのクラスベースViewがテンプレートに何を渡すかを見たいときは、そのクラスにあるget_context_dataというメソッドを追うと良いです。

今回のクラスだと、

DiaryListView -> ListView -> BaseListView -> MultipleObjectMixin

と追うことができます。
(ListViewから先は、djangoのソースです。GitHubだとここ

MultipleObjectMixinで初めてget_context_dataを見つけることが出来ます。
この処理の過程で、Viewに指定したmodelを元に、xxxx_listという変数を用意していることがわかります。
context_object_nameという部分です)

投稿2020/09/27 07:31

attakei

総合スコア2740

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fukazume

2020/09/29 01:41

お返事が遅くなり、大変申し訳ございません。素晴らしいご回答をいただき誠にありがとうございます!django shell、存じ上げませんでした!これで自分の想像だけで値を仮定して闇雲にrunserverを連発してエラー潰ししている現状を劇的に改善できそうな気がします! 補題の件、おそらくobject_listという変数名が既定なんですね。こういった暗黙の命名規則?に関して現在演習に使っている教則本では一切触れられていなかったのでattakeiさんのアドバイスが大変参考になりました! 感謝感謝でございます!m(._.)m
fukazume

2020/09/29 01:44

結果だけでなく、どうしてこうなるかという論理プロセスも順序立ててご解説いただくには相応のお時間を要されたと想像いたします。改めてありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問