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?
view #1
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)
template #1 --Works:
{% block content %}
<h1>Index:</h1>
This blog has a total of {{num_posts}} posts by {{ num_authors}} authors.
{% endblock %}
view #2
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
template#2 - not totally working:
{% block content %}
<h1>All Posts:</h1>
This blog has a total of {{num_posts}} posts by {{ num_authors}} authors.
{% endblock %}
Your definition of the
get_context_datamethod does not update all the variables you expect to be using within your template. For instance, thecontextclass variable is not the same thing as thecontextvariable you are returning inside theget_context_datamethod. Therefore, the only variable to which you have access in the template isnum_authors. To make sure you have all the needed variables within your template, you need to editget_context_datato update thecontextwith the dictionary defined at the class level:Two main updates are made to your original code snippet: the class variable
contextis changed tocontext_varsto avoid conflicts and confusion; and thecontextvariable within theget_context_datamethod isupdatedwith the contents ofcontext_vars. This will make sure that everything defined at the class level (i.e.PostListView.context_vars) makes it to your template.