I'm trying to create a fairly simple form that will allow me to update and delete instruments from a database. Everything is working except for HTML rendering, and for that I'm using django-crispy-forms.
The following code works really well if all I want is a Submit button:
forms.py
class InstrumentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(InstrumentForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
# Add a submit button after all of my fields are auto generated in the form.
self.helper.add_input(Submit('submit', 'Submit'))
class Meta:
model = Instrument
views.py
class InstrumentDetailView(generic.UpdateView):
template_name = 'instrument/details.html'
form_class = InstrumentForm
# FIXME Don't hardcode the URL
success_url = '/inventory/instruments'
model = Instrument
instrument/details.html
{% extends "shared/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h1>Instrument Details</h1>
{% crispy form %}
{% endblock %}
With this configuration, I see all of the fields from my Instrument model rendered perfectly with a Submit button that works.
The problem is that I want to render a "Delete" link next to that Submit button. I've tried the following:
forms.py
class InstrumentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(InstrumentForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
# Add a submit button after all of my fields are auto generated in the form.
self.helper.add_input(Submit('submit', 'Submit'))
self.helper.add_input(HTML('<a href=foo>foo</a>'))
class Meta:
model = Instrument
But that just renders a button that looks like this:
<input name="" value="" class="" id="-id-" type="">
So it looks like add_input
only works for buttons. I then tried the following:
forms.py
class InstrumentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(InstrumentForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
button_layout = Layout(
ButtonHolder(
Submit('submit', 'Submit'),
HTML('<a href="foo">foo</a>')
),
)
self.helper.add_layout(button_layout)
class Meta:
model = Instrument
This does actually render my button and link properly, but all of the other fields disappear. I can of course fix this by manually specifying all of the fields in my InstrumentForm class, but I was hoping to avoid that code duplication.
Does anyone know of a way to only append a submit button and arbitrary link to the bottom of an auto-generated form using django-crispy-form? What am I missing?
Here's what I ended up putting in my forms.py
file to make this work with Twitter bootstrap:
class InstrumentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(InstrumentForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit('submit', 'Submit'))
self.helper.add_input(Button('delete', 'Delete', onclick='window.location.href="{}"'.format('delete')))
class Meta:
model = Instrument
Now the Delete button is right next to the Submit button and I don't have to explicitly define any of my other form fields. The Submit button works and I am sent to the following URL when I click on the delete button for item #1:
http://foo/inventory/instruments/1/delete