I'm currently going through Django's official tutorial, and I'm having trouble trying to understand how the generic views actually work.
Source code from the official documentation:
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
detail.html
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
results.html
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' question.id %}">Vote again?</a>
Now, I understand that ListView
and DetailView
are default generic views provided by Django.
How do DetailView
and ResultsView
generate the question
context variable in the detail.html
and result.html
? Also, how is the error_message
context variable inside the detail.html
generated by the DetailView
?
The question
object is named after the model
attribute of the generic view (in this case, Question
). Detail views include such an object automatically.
If you're asking how the specific question
object is chosen, a detail view, by default, must be passed a pk
value from the URL, which is then used to find that object. The relevant code from polls/urls.py is as follows:
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
error_message
, on the other hand, is not included in the generic views. It's only used in the example for the non-generic view, because that one includes it in the context explicitly:
return render(request, 'polls/detail.html', {
'question': p,
'error_message': "You didn't select a choice.",
})