Django: adding extra context data to a CreateView

Welcome back to another episode of my Django mini-tutorials! In this post we see how to add extra context data to a Django CreateView.

What context there is in a CreateView?

I already touched CreateView in this tutorial. In brief, CreateView is a Django class-based view complete of everything you need to create HTML forms in your Django pages.

Here's how a CreateView looks like:

class TicketCreate(CreateView):
model = Ticket
fields = ["subject", "message", "priority", "attachment"]
success_url = reverse_lazy("clientarea")

In this class-based view you specify a model to operate on, the fields you want to expose, and an optional success_url to redirect the user to, once the form has been successfully submitted.

Now, a CreateView usually renders also a default template (unless you change it), which by convention takes the name of the model, followed by the word "form". For this CreateView for example, the template is ticket_form.html, which should be created beforehand in the template folder.

Once rendered, the template gets a context, which in this case will include a form object which we can then render in the template.

So, CreateView renders a form for editing the model, what if we want to include extra context data?

Adding extra context data to a CreateView

In a Django ListView, the class-based view for listing models, we can override get_queryset() to change the default queryset, but also for adding more data to the related template:

class ClientArea(ListView):
template_name = "support/index.html"

def get_queryset(self):
user = self.request.user
return user.ticket_set.all()

This is useful when you need dynamic context data depending on the logged in user, for example. Another option would be the extra_context attribute, which is more handy for static data.

To add extra context data to a CreateView instead, get_queryset() is not the right method to mess with, because this type of view uses get_queryset() method for fetching the model to operate on.

The method you should override instead is get_context_data(), where you can attach extra context safely. Here's an example:

class TicketCreate(CreateView):
model = Ticket
fields = ["subject", "message", "priority", "attachment"]
success_url = reverse_lazy("clientarea")

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user = self.request.user
context["ticket_list"] = user.ticket_set.all()
return context

The template attached to this view will now have a ticket_list object available in the context.

Thanks for reading and stay tuned!

Valentino Gagliardi

Hi! I'm Valentino! I'm a freelance consultant with a wealth of experience in the IT industry. I spent the last years as a frontend consultant, providing advice and help, coaching and training on JavaScript, testing, and software development. Let's get in touch!