Search code examples
djangodjango-generic-views

Extending generic view classes for common get_context_data


I constantly see myself having to add the same extra variable to the context of many of my views.

def get_context_data(self, **kwargs):
    # Call the base implementation first to get a context
    context = super(MyListView, self).get_context_data(**kwargs)
    # Add in the house
    context['house'] = self.get_object().house
    return context

As I don't like repeating myself, I thought I could create a new class extending the view, and then I could base all my views on the new extended view class. The thing is, there are 4 classes of views I use: CreateView, UpdateView, ListView, and DeleteView. Do I really have to create a new class for each one of them?

Isn't there something like a Django "base" view class? Maybe a smarter way to do this?


Solution

  • Create a Mixin:

    from django.views.generic.base import ContextMixin
    
    class HouseMixin(ContextMixin):
      def get_house(self):
        # Get the house somehow
        return house
    
      def get_context_data(self, **kwargs):
        ctx = super(HouseMixin, self).get_context_data(**kwargs)
        ctx['house'] = self.get_house()
        return ctx
    

    Then in your other classes you'd use multiple inheritance:

    class HouseEditView(HouseMixin, UpdateView):
      pass
    
    class HouseListView(HouseMixin, ListView):
      pass
    

    and so on, then all these views will have house in the context.