Djangoのチュートリアル 4 HTMLに慣れる
Djangoのチュートリアルの第4弾です。過去の記事はこちらです。
Djangoのチュートリアル 1 インストールから最初のビュー作成まで - pyhaya’s diary
Djangoのチュートリアル 2 モデルを作成する - pyhaya’s diary
pyhaya.hatenablog.com
前回は、DjangoでのWebページのデザインに限界を感じ、HTMLによる記述に心移りするところまで行きました。正直私は今までバックエンドの勉強ばかりでWebページのようなフロントエンドはさぼってきました。なので、ここで少しHTMLの練習もかねて、ビューのindex
が呼ばれたときに表示されるページを編集してみようと思います。
ただし、必要最低限です。あまり作りこんだりCSSとか編集しだしたら初心者にはわかりにくい記事になってしまうし、何より私が把握できなくなりますww。
目次
何を作るか
前回の記事では、データベースに登録していたQuestionをindex.html
に表示させるところまで書きました。ここで、各Questionにはリンクが張られていてクリックすると「Hello, World. This is polls application number 1」とかQuestionのIDが表示されていました。
今回編集するのは、この、クリックしたときに飛ぶページです。前回まではビューのdetail
にべた書きしてました。これをHTMLに任せようと思います。具体的にこのページは何を表示すべきでしょうか?Questionをクリックして飛んでくるので、以下のようなページがよさそうです。
- クリックされたQuestionに対する選択肢(Choiceを
models.py
に作ったのを覚えているでしょうか)が表示される - Questionがページ上部に大きく表示される
ビューを編集する
では、index
関数を参考にdetail
関数を作ってみます。
polls/views.py
from django.shortcuts import render from .models import Question # Create your views here. def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list' : latest_question_list} return render(request, 'polls/index.html', context) def detail(request, question_id): question = Question.objects.get(pk=question_id) return render(request, 'polls/detail.html', {'question' : question})
detail
では、Questionをコンテクストとして与えてdetail.html
に渡します。これを受け取ったdetail.html
は、Questionをもとに、そこに紐づけられている選択肢を取得し、表示します。この時、detail.html
は、
<!DOCTYPE html> <html> <head> <meta charset='utf-8'> </head> <body> <h1>{{ question.question_text }} </h1> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </body> </html>
質問文であるquestion_text
はh1タグを付けてでかでかと表示します。次は、紐づけられている選択肢を表示します。これにはfor文を用いるのが良いでしょう。HTML内でfor文を使うときには{% %}
で囲み、最後には{% endfor %}
を付けるのでした。
choice_set
というのはここではじめてあらわれました。これについて少し書いておきます。
choice_set
とは?
せっかくなのでここでモデルどうしの関係性を整理しておきます。下の図を見てください。
一番左がユーザー、というかプログラマで、プログラマはQuestion
モデルを見ています。Questionのオブジェクトは、Question.objects
として存在しています。Questionオブジェクトが全部ほしいときにはプログラマは
Question.objects.all()
と書くことで全部取得できます。
各QuestionオブジェクトにはそれぞれいくつかのChoiceオブジェクトが紐づけられています。ここではQuestion1, Question2にそれぞれChoice1-1やChoice2-1などが紐づけられています。ここでQuestion1に紐づけられているChoiceはQuestion1.choice_set
に入っています。これを取り出したかったら
Question1.choice_set.all()
とすることで全部取得できます。ここで、choice_set
という名前ですが、これがDjangoの提供するメソッドの名前そのものというわけではなくて、Questionに紐づけられているのがChoiceだからこれを小文字にして_set
を付けているだけです。だからQuestionに紐づけられているクラスの名前がfoo
だったらこれはfoo_set
とします。これは次のやり取りが参考になると思います。
stackoverflow.com
Webページを表示してみる
ではサーバーを動かしてページを見てみましょう。
http://127.0.0.1:8000/pollsを見てみると、登録したQuestionの一覧が出てきて、一つクリックすると質問文が大きく表示され、、、その下には何も表示されていません。そういえばChoiceは一つも登録していませんでした。polls/admin.py
にChoiceを登録して
http://127.0.0.1:8000/adminページからChoiceをいくつか登録してみます。
polls/admin.py
from django.contrib import admin from .models import Question, Choice # Register your models here. admin.site.register(Question) admin.site.register(Choice)
これで質問文の下に選択肢が表示されるようになります。
まとめ
今回はここまでです。今回やったことは
- HTMLの練習をした
- Choiceのデータを取り出す方法を学んだ
です。