Reputation: 5540
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
?
Upvotes: 0
Views: 158
Reputation: 8061
DetailView has a context_object_name
parameter, which you can use to set the name of the object in the template, but if you don't set it, the get_context_object_name
method does this:
def get_context_object_name(self, obj):
"""
Get the name to use for the object.
"""
if self.context_object_name:
return self.context_object_name
elif isinstance(obj, models.Model):
return obj._meta.model_name
else:
return None
It uses the name of the model. Then get_context_data
of the SingleObjectMixin
puts that identifier in the context. In any case, you can also access the object with the object
identifier.
I'm sure you can read all of this in the Django documentation, but there is a nice page where you can explore class based views
Upvotes: 1
Reputation: 3387
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.",
})
Upvotes: 2