How to use context with class in CreateView in django?
Before i have:
#views.py
from django.views.generic import CreateView
from cars.models import *
You have to use get_context_data
class CreateCar(CreateView):
info_sended = False
template_name = 'create_car.html'
model = Car
success_url = 'create_car' #urls name
def form_valid(self, form):
self.info_sended = True
return super(CreateCar, self).form_valid(form)
def get_context_data(self, **kwargs):
ctx = super(CreateCar, self).get_context_data(**kwargs)
ctx['info_sended'] = self.info_sended
return ctx
If you see the django source CreateView inherits from BaseCreateView this one inherits from ModelFormMixin in turn this one inherits from FormMixin and this one inherits from ContextMixin and the only method this one defines is get_context_data
.
Hope this helps you.
PD: This may be a bit confusing for better understanding of inheritance in Python feel free of read this article about MRO.
You should define get_context_data() method in your class view. Update your code as
from django.shortcuts import render
class CreateCar(CreateView):
info_sended = False
template_name = 'create_car.html'
model = Car
success_url = 'create_car' #urls name
def form_valid(self, form):
self.info_sended = True
# Instead of return this HttpResponseRedirect, return an
# new rendered page
super(CreateCar, self).form_valid(form)
return render(self.request, self.template_name,
self.get_context_data(form=form))
def get_context_data(self, **kwargs):
ctx = super(CreateCar, self).get_context_data(**kwargs)
ctx['info_sended'] = self.info_sended
return ctx
Since your are creating a new instance of a Car, there is no context for get_context_data
because there is no object yet. I didn't test using Mixin to get the context from another class as suggested above, but that seems reasonable. However, if I can assume you want to use the basic CreateView
, UpdateView
and DeleteView
, then I solved this by assuming I will have no context for CreateView
. Then in my template I used an if to make the decision, such as:
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value={% if not buttonword %}Save{% else %}{{ buttonword }}{% endif %}>
</form>
In DeleteView
I include:
context['buttonword'] = 'Delete'
In UpdateView
I include:
context['buttonword'] = 'Update'
As I said, I do not set buttonword
in CreateView
. Hence, when the template logic is done, if buttonword
is assigned, the word in it shows up in the button, otherwise Save shows up on the button.