What method should you override when you want extra context data in a Django 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
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.
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.
CreateView renders a form for editing the model, what if we want to include extra context data?
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
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!