Tom Purl
Tom Purl

Reputation: 549

Can't Just Append A Delete Button To A Crispy Form

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?

Upvotes: 1

Views: 2516

Answers (2)

davesave
davesave

Reputation: 2934

my form code:

class PersonForm(forms.ModelForm):
class Meta:
    model = Person
    fields = ('name', 'email', 'job_title', 'bio')

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.helper = FormHelper()
    self.helper.form_method = 'post'
    self.helper.add_input(Submit('submit', 'Save person'))
    if kwargs['instance']:
        self.helper.add_input(Button('delete', 'Delete', onclick='window.location.href="{}"'.format('../delete')))

my urls.py contains:

path('<int:pk>/delete/', views.PersonDeleteView.as_view(), name='person_delete')

Upvotes: 0

Tom Purl
Tom Purl

Reputation: 549

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

Upvotes: 3

Related Questions