I am using the bootstrap4/table_inline_formset.html
template in a FormHelper
from django-crispy-forms
. The table is rendered correctly in the template, but an extra form always appears at the beginning of the table, which is not visible when submitting the form.
forms.py:
class MetricForm(forms.ModelForm):
class Meta:
model = Metric
exclude = ['auto_value','occurrence']
class MetricFormSetHelper(FormHelper):
def __init__(self, *args, **kwargs):
super(MetricFormSetHelper, self).__init__(*args, **kwargs)
self.add_input(Submit('submit', 'Submit', css_class="btn btn-success"))
self.template = 'bootstrap4/table_inline_formset.html'
views.py:
@login_required
def create_occurrence(request, pk):
try:
site = Site.objects.get(id=pk)
except Site.DoesNotExist:
raise Http404("Site does not exist")
form = OccurrenceForm(request.POST or None, initial={'site':site})
MetricFormset = modelformset_factory(Metric, form=MetricForm, extra=3)
formset = MetricFormset(queryset=Metric.objects.none())
helper = MetricFormSetHelper()
if form.is_valid():
occurrence = form.save(commit=False)
occurrence.added_by = request.user
occurrence.site = site
occurrence.save()
form.save_m2m()
metric_formset = MetricFormset(request.POST)
if metric_formset.is_valid():
for metric_form in metric_formset.forms:
if all([metric_form.is_valid(), metric_form.cleaned_data != {}]):
metric = metric_form.save(commit=False)
metric.occurrence = occurrence
metric.save()
messages.success(request, "Occurrence created successfully.")
execute_from_command_line(["../manage_dev.sh", "updatelayers", "-s", "archaeology"])
return redirect(occurrence.get_absolute_url())
context = {
'form': form,
'site':site,
'formset':formset,
'helper': helper,
}
return render(request, "archaeology/occurrence_form.html", context=context)
template:
...
<form action="" method="post">
{% csrf_token %}
{{ form|crispy }}
<h4>Metrics</h4>
{{ formset.management_form }}
{% crispy formset helper %}
{% if form.instance.pk != None %}
<a class="btn btn-danger" href="{% url 'delete_occurrence' occurrence.id %}">{% trans "Delete" %}</a>
{% endif %}
</form>
...
Any idea how to remove the extra row?
I had to change the template and remove the lines that printed an empty form at the beginning.
table_inline_formset.html:
<tr class="d-none empty-form">
{% for field in formset.empty_form %}
{% include 'bootstrap4/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr>