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!
