Reputation: 1499
I'm new to Django. I want to use a mixin to return some data to multiple class based views. It seems the get_context_data
I defined in mixin is not called in the view class.
class MyMixin(object):
def get_context_data(self, *args, **kwargs):
data = super(MyMixin, self).get_context_data(*args, **kwargs)
from django.utils import timezone
data['object'].now = timezone.now()
return data
class PageDetail(DetailView, MyMixin):
model = MyModel
template_name = 'page-detail.html'
def get_context_data(self, *args, **kwargs):
data = super(PageDetail, self).get_context_data(*args, **kwargs)
return data
Upvotes: 3
Views: 913
Reputation: 476967
You define the base classes in the wrong order:
class PageDetail(DetailView, MyMixin):
# ...
means that the method resolution order (MRO) is defined as:
>>> PageDetail.__mro__
(<class 'PageDetail'>,
<class 'django.views.generic.detail.DetailView'>,
<class 'django.views.generic.detail.SingleObjectTemplateResponseMixin'>,
<class 'django.views.generic.base.TemplateResponseMixin'>,
<class 'django.views.generic.detail.BaseDetailView'>,
<class 'django.views.generic.detail.SingleObjectMixin'>,
<class 'django.views.generic.base.ContextMixin'>,
<class 'django.views.generic.base.View'>,
<class 'MyMixin'>,
<class 'object'>)
So that means that if we follow the super(PageDetail, self).get_context_data(*args, **kwargs)
, this will never reach MyMixin
, since the ContextMixin
defines this as:
class ContextMixin: def get_context_data(self, **kwargs): if 'view' not in kwargs: kwargs['view'] = self if self.extra_context is not None: kwargs.update(self.extra_context) return kwargs
and thus does not call any super()
method.
You should define your PageDetail
as:
class PageDetail(MyMixin, DetailView):
# ...
So now the MRO is defined as:
>>> PageDetail.__mro__
(<class 'PageDetail'>,
<class 'MyMixin'>,
<class 'django.views.generic.detail.DetailView'>,
<class 'django.views.generic.detail.SingleObjectTemplateResponseMixin'>,
<class 'django.views.generic.base.TemplateResponseMixin'>,
<class 'django.views.generic.detail.BaseDetailView'>,
<class 'django.views.generic.detail.SingleObjectMixin'>,
<class 'django.views.generic.base.ContextMixin'>,
<class 'django.views.generic.base.View'>,
<class 'object'>)
and thus the super(PageDetail, self).get_context_data(*args, **kwargs)
will call the get_context_data
of the MyMixin
class, which then will call the method next in the MRO.
Upvotes: 6