Class Based Views

@views @cbv @classbasedview

This page has snippets and hints for class based views. Because function based views are so similar in what they can do, I will usually link items here back to the equivalent article in FBVs.

Passing additional context data to CBVs

@context @forms

Sometimes we want to pass additional data to class based views. With FBVs, this is trivial and quite obvious, as we construct the context ourselves as a dict ourselves (using queries, etc) and then return that to the template. We do this by calling the return() function in the first level of the body of the function based view definition:

# An example view
def MyView(request, **kwargs):
	# ...
	# create the context data here
	# ...
	return render(request, 'template.html', {'context_data': context_data})
	

With CBVs, for some reason we can't do it the same way (because CBV's are "tied" to a model), and in any case, we use get_object() to return the context to the template instead of render(). So instead we have to extend the get_context_data() function of the generic CBV to pas additional context:

class MyView(generic.DetailView):
	template_name = 'template.html'
	model = SomeModel

	# This is equivalent to render() in a FBV
	def get_object(self):
		# ...
		# create the context (has to be an object)		
		# ...
		return context_object


	# Now I override the get_context_data function to add additional data
	def get_context_data(self, **kwargs):
		context = super(MyView, self).get_context_data(**kwargs)
		context['additional_context'] = #some context
		return context

MOST IMPORTANTLY: In the CBV, we can even pass a form as the context and display that form on the same template that is rendering the view (a DetailView or ListView for example). VERY CONVENIENT because you don't need to do any of the handling of the form in the CBV like you have to do in the FBV (by doing if request=='POST' etc). The form already knows what your model is, so really why should we have to manually set all the model fields equal to the form POST fields? It's just tedious.

Pretty cool and pretty useful.