djangodjango-formsdjango-templatesformset

Output django formset as table rows


I have a Django formset which I'd like to output as one table row per nested form like so:

<form>
    {{ feature_formset.management_form }}
    <table>
    {% for form in feature_formset %}
        <tr>
            {% for field in form %}
            <td>{{ field.name }} {{ field }}</td>
            {% endfor %}
        </tr>
    </table>
    {% endfor %}
</form>

However, somehow (I think) the automatic field rendering gets confused by the table wrapper.

What I'd expect would be output like:

<form>
    ...
    <table>
        <tr>
            <td>id: <input ...></td>
            <td>name: <input ...></td>
            <td>foobar: <input ...></td>
        </tr>
        <tr>
            <td>id: <input ...></td>
            <td>name: <input ...></td>
            <td>foobar: <input ...></td>
        </tr>
        <tr>
            <td>id: <input ...></td>
            <td>name: <input ...></td>
            <td>foobar: <input ...></td>
        </tr>
    </table>
    {% endfor %}
</form>

However, what I'm getting is a form row for the first form of the formset, and the rest of the forms just dumping the fields. Somehow the {% for field in form %} does not iterate properly, and I guess the remaining fields are dumped:

<form>
    ...
    <table>
        <tr>
            <td>id: <input ...></td>
            <td>name: <input ...></td>
            <td>foobar: <input ...></td>
        </tr>
        
        id: <input ...>
        name: <input ...>
        foobar: <input ...>
        
        id: <input ...>
        name: <input ...>
        foobar: <input ...>
    </table>
    {% endfor %}
</form>

Any pointers as to why this custom rendering of the nested forms / fields is not working as intended?


Solution

  • You close the table too early, so:

    <form>
        {{ feature_formset.management_form }}
        <table>
        {% for form in feature_formset %}
            <tr>
                {% for field in form %}
                <td>{{ field.name }} {{ field }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
        </table>
    </form>
    

    The </table> is thus put after the {% endfor %}.