eyeinthebrick
eyeinthebrick

Reputation: 548

How to use Django mixin?

In my app I have a bunch of DetailViews and ListViews. I need to add a panel with "last visited pages" info to every page. I know I can make two my own classes inheriting from DetailView and ListView respectively and overriding get_context_data method, but that will dublicate the code. At the moment I solved the problem, by simply adding one line of code to every view

context['panel_info'] = get_panel_info()

but I don't like this solution as well. My idea was to create a Mixin with custom get_context_data method, but as far as I know, if I inherit like this

class MyView(DetailView, MyMixin):
    def get_context_data(self, **kwargs):
        context = super(MyView, self).get_context_data(**kwargs)
        return context

Mixin's method won't be called at all. So what's the cleverest solution to this?

Upvotes: 0

Views: 1684

Answers (2)

Sreejith Ramakrishnan
Sreejith Ramakrishnan

Reputation: 1382

Like BurhanKhalid mentioned, using a template context processor is a clever solution. Context processors let you specify a number of variables that get set in each context automatically.

The only catch is that you need to use RequestContext in place of Context. So,

def my_view(request):
    return render(request, 'template.html', {'whatever': 'whatever'},
                  context_instance=RequestContext(request))

Make the context processor. Its basically a method which takes a HttpRequest and returns a dict.

def last_visited_pages_context_processor(request):
    # Your custom code
    return {'foo': 'bar'}

Now, just add the context processor to TEMPLATE_CONTEXT_PROCESSORS in your settings.py,

TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'your_app.context_processors.last_visited_pages_context_processor',
)

Good to go. More info at http://www.djangobook.com/en/2.0/chapter09.html

Upvotes: 1

petkostas
petkostas

Reputation: 7460

There are different ways to do this, if you need something reusable to all of your views then a context processor might be the solution, yet if you need it only on some specific views then a Mixin might also do the trick. How you do it:

class MyMixin(object):

    def get_context_data(self, **kwargs):
        context = super(MyMixin, self).get_context_data(**kwargs)
        context['panel_info'] = get_panel_info()
        return context


class MyView(MyMixin, DetailView):
   ...

You don't need to override the get_context_data in your MyView for the Mixin to work.

Upvotes: 2

Related Questions