Reputation: 1252
Help me understand how to use Django's context
--Is the issue related to the use of context
in function-based vs class-based views:
I have created two views (index
and post_list
) and respective templates (following the Assessment portion of the Mozilla Django Tutorial). The code for index
works, but identical code for post_list
doesn't. Why is that?
def index(request):
post_list = Post.objects.all()
num_posts = Post.objects.all().count()
num_comments = Comment.objects.all().count()
num_authors = Author.objects.count()
num_commenters = Commenter.objects.count()
context = {
'num_posts': num_posts,
'num_comments': num_comments,
'num_authors': num_authors,
'num_commenters': num_commenters,
'post_list' : post_list,
}
return render(request, 'index.html', context=context)
{% block content %}
<h1>Index:</h1>
This blog has a total of {{num_posts}} posts by {{ num_authors}} authors.
{% endblock %}
class PostListView(generic.ListView):
model = Post
post_list = Post.objects.all()
num_posts = Post.objects.all().count()
num_authors = Author.objects.count()
template_name = 'blog/post_list.html'
context = {
'num_posts': num_posts,
#'num_authors': num_authors, # Removed b/c it doesn't work
'post_list' : post_list,
}
def get_context_data(self, **kwargs):
context = super(PostListView, self).get_context_data(**kwargs)
context['num_authors'] = Author.objects.count() # But this works!
return context #edited, this line was left out in the original post
{% block content %}
<h1>All Posts:</h1>
This blog has a total of {{num_posts}} posts by {{ num_authors}} authors.
{% endblock %}
Upvotes: 2
Views: 2811
Reputation: 13274
Your definition of the get_context_data
method does not update all the variables you expect to be using within your template. For instance, the context
class variable is not the same thing as the context
variable you are returning inside the get_context_data
method. Therefore, the only variable to which you have access in the template is num_authors
. To make sure you have all the needed variables within your template, you need to edit get_context_data
to update the context
with the dictionary defined at the class level:
class PostListView(generic.ListView):
model = Post
post_list = Post.objects.all()
num_posts = Post.objects.all().count()
num_authors = Author.objects.count()
template_name = 'blog/post_list.html'
context_vars = {
'num_posts': num_posts,
'num_authors': num_authors,
'post_list' : post_list,
}
def get_context_data(self, **kwargs):
context = super(PostListView, self).get_context_data(**kwargs)
context.update(PostListView.context_vars)
return context
Two main updates are made to your original code snippet: the class variable context
is changed to context_vars
to avoid conflicts and confusion; and the context
variable within the get_context_data
method is updated
with the contents of context_vars
. This will make sure that everything defined at the class level (i.e. PostListView.context_vars
) makes it to your template.
Upvotes: 3