Django's Class-Based-Views inheritance
Lately, I've been moving away from django's Function-Based-Views (FBV) to Class-Based-Views (CBV) (which, by the way, are awesome and I recommend you to use it) and I found my self keep overiding the get_context_data()
(who's job is to return the context dict which will be used in the template) method.
Since the big advantage of using CBV's over FBV's are inheritance, we could eliminate the code repetition I had in my get_context_data()
Solution
This class CourseContextMixin()
is the class I'm going to inherit from for my other views, so that they'll all use the same get_context_data()
. In my case, I wanted to pass the profile variable which contains information about the signed in user to the template.
# Base class which my other views will inherit
class CourseContextMixin(ContextMixin, View): # since I need the request param, I'm including the View class
def get_context_data(self, **kwargs):
context = super(CourseContextMixin, self).get_context_data(**kwargs)
profile = get_object_or_404(Profile, user__username=self.request.user)
context['profile'] = profile
return context
All my other views now will inherit CourseContextMixin
and will not need to override the get_context_data()
method.
@method_decorator(login_required, name='dispatch')
class CourseDetailView(CourseContextMixin, DetailView):
model = Course
template_name = 'course_detail.html'
def get_queryset(self):
slug = self.kwargs.get('slug', None)
abbrv = self.kwargs.get('abbreviation', None)
number = self.kwargs.get('number', None)
profile = get_object_or_404(Profile, user__username=self.request.user)
return super(CourseDetailView, self).get_queryset().filter(instructor=profile,
slug=slug,
abbreviation=abbrv,
number=number,
)
@method_decorator(login_required, name='dispatch')
class CourseListView(CourseContextMixin, ListView):
model = Course
template_name = 'course_list.html'
def get_queryset(self):
profile = get_object_or_404(Profile, user__username=self.request.user)
return super(CourseListView, self).get_queryset().filter(instructor=profile)
@method_decorator(login_required, name='dispatch')
class CourseCreateView(CourseContextMixin, CreateView):
model = Course
template_name = 'course_form.html'
success_url = reverse_lazy('course-create-complete')
form_class = CourseForm
object = None
def form_valid(self, form):
self.object = form.save(commit=False)
instructor = get_object_or_404(Profile, user__username=self.request.user)
self.object.instructor = instructor
self.object.save()
return HttpResponseRedirect(self.get_success_url())
Thanks for reading! and let me know if you have any feedback.