要約
もっとビューを書いてみる
path("[/polls/に続くURL]", viewsディレクトリの中の呼び出す関数名, 名前付け)
def detail(request, pathからの引数)
# polls/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
def detail(request, question_id):
return HttpResponse("You're looking at question %s. " % question_id)
def results(request, question_id):
response = "You're looking as the results of question %s. "
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
# ------------------------------
# polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name = "index"),
path("<int:question_id>/", views.detail, name = "detail"),
path("<int:question_id>/results/", views.results, name = "results"),
path("<int:question_id>/vote/", views.vote, name = "vote"),
]
<int:question_id>
の部分はなんでも良いが、下記のように揃える。
polls/detail/
に関する部分を<int:question_idaaa>
に変更しても、正常に動作する。
# polls/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
def detail(request, question_idaaa):#変更
return HttpResponse("You're looking at question %s. " % question_idaaa)#変更
def results(request, question_id):
response = "You're looking as the results of question %s. "
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
# ------------------------------
# polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name = "index"),
path("<int:question_idaaa>/", views.detail, name = "detail"),#変更
path("<int:question_id>/results/", views.results, name = "results"),
path("<int:question_id>/vote/", views.vote, name = "vote"),
]
実際に動作するビューを書く
render(request, テンプレート名, 辞書)
テンプレートがない場合は、HttpResponse
を使えばいい。(render
はテンプレートの読み込みをショートカットできる)
render
の引数にcontext
を渡すことで、index.html
側でcontext(latest_question_list)
を受け取ることができる。
# polls/views.py
from django.shortcuts import render
from .models import Question
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)
# ------------------------------
# polls/templates/polls/index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href = "/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>Mo polls are available.</p>
{% endif %}
つまり、template = loader.get_template('polls/index.html')
を書かなくてよくなるということ。
404エラー
get_object_or_404(モデル名, 404を出したい時のキーワードを指定)
404にならない時は、question = Question.objects.get(pk=question_id)
と同等の扱いになる。
# polls/views.py
from django.shortcuts import render, get_object_or_404
def detail(request, question_id):
question = get_object_or_404(Question, pk = question_id)
return render(request, "polls/detail.html", {"question": question})
テンプレートシステムを使う
テンプレート側(detail.html
)ではviews
から渡された変数(question
)に、.
をつけて検索できる。
# polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
# ------------------------------
# polls/views.py
def detail(request, question_id):
question = get_object_or_404(Question, pk = question_id)
return render(request, "polls/detail.html", {"question": question})
テンプレート内のハードコードされたURLを削除
<a href="/polls/{{ question.id }}/">
を<a href = "{% url 'detail' question.id %}">
に変更できる。
こうしておくことで、URLの変更は、polls/urls.py
側だけで良くなる。
# polls/urls.py
path("<int:question_id>/", views.detail, name = "detail"),
# ------------------------------
# polls/templates/polls/index.html
<li><a href = "{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
Djangoに複数アプリが存在する場合は、app_name
を指定しておくといい。
# polls/urls.py
app_name = "polls"#追加
urlpatterns = [
path("", views.index, name = "index"),
path("<int:question_id>/", views.detail, name = "detail"),
path("<int:question_id>/results/", views.results, name = "results"),
path("<int:question_id>/vote/", views.vote, name = "vote"),
]
# ------------------------------
# polls/templates/polls/index.html
<li><a href = "{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>