4

When i render my formset using a loop, everything works.

When i try to render it manually by accessing each field separately ( for frontend purpose ) the form is rendering but the submit fail. Every fields are the same, so i guess there is a hidden field created when working with the formset that i dont know about.

Here a simplified sample of my working code

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
{{ formset.management_form }}
{% for p in formset %}
    {{p.as_p}}
    {% endfor %}
</form>

And a simplified example of what is not working

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
{{ formset.management_form }}
{% for p in formset %}
<span class="form-sub-label-container " style="vertical-align:top">
                    {{p.field1}}
                    <label class="form-sub-label" for="input_12_city" id="sublabel_12_city" style="min-height:13px"></label>
                  </span>
    < span class="another_span">
    {{p.field2}}
 </span>
## etc....
    {% endfor %}
</form>

Any idea ?

Thanks.

dsimond
  • 103
  • 1
  • 10

1 Answers1

7

If you want to render each formset form field manually, you have to add Django default hidden fields.

<form method="post">
    {% csrf_token %}
    {{ formset.management_form }}
    {% for p in formset %}
        {{ p.id }} # if formset is ModelFormSet
        {{ p.ORDER }} # if can_order=True
        {{ p.DELETE }} # if can_delete=True
        ... # your custom fields
    {% endfor %}
</form>
EMiDU
  • 654
  • 1
  • 7
  • 24
  • It's tricky, as long as documentation does not mention anything about those hidden fields, except optional ORDER and DELETE fields: https://docs.djangoproject.com/en/3.0/topics/forms/formsets/#manually-rendered-can-delete-and-can-order – EMiDU Jan 22 '20 at 16:06
  • It is in the docs ... https://docs.djangoproject.com/en/3.0/topics/forms/formsets/#understanding-the-managementform – nigel222 Jan 22 '20 at 16:37
  • @nigel222 There is no information about `id` field, which is necessary whenever you want to manually render form fields in formsets. – EMiDU Jan 22 '20 at 16:43
  • @EMiDU sorry, didn't register that. I can't see an `id`. With django 2.2.8 shell, I instantiate `fs = Formset({ 'form-TOTAL_FORMS': ...} )` then `for f in fs: print( f.id)` and it says "no attribute id". Something new and undocumented in Django 3 only? – nigel222 Jan 22 '20 at 17:19
  • @nigel222 Youe are right, `id` field is required only when you are using ModelFormSet (I've updated my answer). Please refer to: https://stackoverflow.com/a/55361551/5612001 – EMiDU Jan 22 '20 at 18:51
  • I've read the doc and didn't seen anything about id, even before i asked the question. For order and delete yes, but as the doc says, it's only required if you want to set it to True. Adding the id made it work properly. – dsimond Jan 23 '20 at 08:25