Reputation: 9782
I am just beginning to wrap my head around what super
is and how it is implemented in view based classes in Django. I am trying to understand how super is working in the following code. Could someone try to break it down for me piece by piece?
from django.views.generic.detail import DetailView
from apps.app_name.models import Article
class ArticleDetailView(DetailView):
model = Article
template_name = 'article/show.html'
def get_context_data(self, **kwargs):
context = super(ArticleDetailView, self).get_context_data(**kwargs)
return context
Upvotes: 4
Views: 3463
Reputation: 362786
As currently written, the method does absolutely nothing and could be removed.
The context data method is directly delegated to the next class in the inheritance chain. In this case, it would mean the superclass DetailView.get_context_data
is used.
However, this would happen anyway if the method was not present on ArticleDetailView
. So it's pointless to write it like that, passing onto the superclass explicitly.
So, the code is just strange - does this answer your question?
If you actually wanted to do something different in the subclass, for example, then it would make sense to implement this method. For example:
def get_context_data(self, **kwargs):
context = super(ArticleDetailView, self).get_context_data(**kwargs)
context['new_key'] = 'some injected context from ArticleDetailView'
return context
Then we are using the context data from DetailView
, and adding additional context in ArticleDetailView
.
The reason to use super(ArticleDetailView, self).get_context_data
instead of just simply using DetailView.get_context_data
directly is complicated, and related to the method resolution order (MRO). It's explained in some detail by Raymond Hettinger over here.
Note: in python 3 the implementation of super is cleaned up a bit, and you no longer need super(ArticleDetailView, self)
you can just use super()
thankfully.
Upvotes: 5
Reputation: 10256
The super
method will access to the current class and call an specific method, in this case:
super(ArticleDetailView, self) # Access to the current class
And execute an specific method:
.get_context_data(**kwargs)
The .get_context_data()
method in a View
class, returns the context
passed to the template (.html
file). In this case, you're using a DetailView
, so you have some predefined context, such as: object
or article
.
If you just override .get_context_data()
without calling .super()
, like this:
def get_context_data(self, **kwargs):
my_context = {...}
return my_context
You will lost the predefined variables in the DetailView
context. But if you want to add some new variables (values) to the current DetailView
's context, you need the original context, and that's what super(ArticleDetailView, self).get_context_data(**kwargs)
will give you. So you will use it in this way:
def get_context_data(self, **kwargs):
context = super(ArticleDetailView, self).get_context_data(**kwargs)
context.update({'my_key': 'my_value'})
return context
Now you will be able to use your own value in the template without losing the default DetailView
's context values.
Upvotes: 7