I am currently trying to show a custom form where I alter the form in the corresponding view
in the .html
<form action="{% url 'systems_system_update' system.id %}" id="system_update_form" method="post" class="form">
{% csrf_token %}
{% buttons %}
<button type="submit" class="btn btn-primary">Update {{ system.name }}</button>
{% endbuttons %}
{% bootstrap_form system_update_form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Update {{ system.name }}</button>
{% endbuttons %}
</form>
So I'm trying to show system_update_form where it is defined in the view in SystemDetailView
class SystemDetailView(DetailView):
"""Detail view for Systems"""
form_class = SystemForm
model = System
template_name = 'systems/system_detail.html'
def get_form(self, form_class):
form = super(SystemDetailView, self).get_form(form_class)
form.fields['primary_purpose_business_use'].label = "Primary purpose/business use"
form.fields['secondary_purpose_business_uses'].label = "Secondary purpose/business uses"
return form
def get_context_data(self, **kwargs):
context = super(SystemDetailView, self).get_context_data(**kwargs)
context.update({
'system_update_form': self.form_class(instance=self.get_object()),
'object_name': self.object.name,
'user_can_edit': self.request.user.has_perm(
'services.change_system'),
'user_can_delete': self.request.user.has_perm(
'services.delete_system'),
'object_events': self.object.events.all(),
})
return context
So, I'm updating the context and setting 'system_update_form' to the form and I'm trying to update the form by using get_form, but I don't think DetailView has the get_form method for overriding. Updating it in the forms is not an option because SystemForm is used in many different places and needs to be altered for this view specifically
DetailView
does not have a get_form()
method as it does not uses a form, thereby your get_form()
method is not being called.
Instead of that, you can manually instantiate the form in your get_form()
method and call this method when generating the context
.
Also, in your code, you are passing instance
to the form by calling self.get_object()
. This will lead to another query for getting the object
as Django has already fetched the object
before. Instead of doing that, you can directly pass object
using self.object
.
class SystemDetailView(DetailView):
def get_form(self):
form = self.form_class(instance=self.object) # instantiate the form
# modify the form fields
form.fields['primary_purpose_business_use'].label = "Primary purpose/business use"
form.fields['secondary_purpose_business_uses'].label = "Secondary purpose/business uses"
return form
def get_context_data(self, **kwargs):
context = super(SystemDetailView, self).get_context_data(**kwargs)
context.update({
'system_update_form': self.get_form(), # get the form instance
'object_name': self.object.name,
'user_can_edit': self.request.user.has_perm(
'services.change_system'),
'user_can_delete': self.request.user.has_perm(
'services.delete_system'),
'object_events': self.object.events.all(),
})
return context