I am reading about Template views through a tutorial and some of the code kind of confused me. The author used this code sample
from django.utils.timezone import now
class AboutUsView(TemplateView):
template_name = 'about_us.html'
def get_context_data(self, **kwargs):
context = super(AboutUsView, self).get_context_data(**kwargs)
if now().weekday() < 5 and 8 < now().hour < 18:
context['open'] = True
else:
context['open'] = False
return context
The thing that confused me syntactically was this statement
context = super(AboutUsView, self).get_context_data(**kwargs)
if we already are receiving **kwargs
then why are we passing it to the super function with ** (double start). I think we should pass it as
context = super(AboutUsView, self).get_context_data(kwargs)
this is the contextMixin which is receiving this call.
class ContextMixin(object):
"""
A default context mixin that passes the keyword arguments received by
get_context_data as the template context.
"""
def get_context_data(self, **kwargs):
if 'view' not in kwargs:
kwargs['view'] = self
return kwargs
From what I have read is that the use of **kwargs
pretty much means that kwargs is currently a dictionary and needs to be converted to named-value. If that is correct then how can kwargs be a dictionary when its parameter is actually **kwargs. I hope my question makes sense. Please let me know if you would want me to rephrase this.
In a function declaration, **kwargs
will take all unspecified keyword arguments and convert them into a dictionary.
>>> test_dict = {'a':1, 'b':2}
>>> def test(**kwargs):
... print (kwargs)
...
>>> test(**test_dict)
{'b': 2, 'a': 1}
Note that the dictionary object has to be converted using **
when it is passed to the function ( test(**test_dict)
) and when it is received by the function. It is impossible to do the following:
>>> test(test_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test() takes 0 positional arguments but 1 was given
So, in your example, the first **kwargs
unpacks the keyword arguments into a dictionary, and then the second packs them back up to be sent to the parent.
A function with **kwargs
in the signature can either received an unpacked dictionary or unspecified keyword arguments. Here's an example of the second case:
>>> def test(arg1, **kwargs):
... print (kwargs)
...
>>> test('first', a=1, b=2)
{'b': 2, 'a': 1}
Here at your function definition, it is accepting multiple arguments, and parsing them into a dict. def get_context_data(self, **kwargs):
So now, kwargs is a dictionary object. So if you pass it to .get_context_data(kwargs)
it would have to expect only a single incoming argument, and treat it as a dictionary.
So when you do **kwargs
a second time, you are blowing up the dictionary back into keyword arguments that will expand into that functions call.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.