How to render form.as_table in multiple columns

Question:

I am using a model form, and I have rendering that form in the template as below.

 <table>
    {{form.as_table}}
 </table>

But the problem is, its rendering all the fields as rows. Since my model contains more than 200 rows,
when its showing the elements as 200 rows its looking bad. I want to divide them into 5 columns, so the
total rows will be around 40-43. Is there any inbuilt template tag available for this or any other way using which we can solve the problem.

Asked By: sandeep

||

Answers:

You can refer this doc: looping over form fields

What you can do in your template is

{% for field in form %}

    {%if forloop.counter|divisibleby:"5" %}
        {#after 5 fields, somehow put elements in next row
         of table, paragraph, or using divs etc
        #}
    {%endif%}

    {{field}}
{%endfor%}
Answered By: Rohan

Your question is a bit unclear however this example is more than enough.

the loop iterates over a list data and I have replaced so that it would display column1,column2,column3,column4,column5 in every row for example purposes.

<!DOCTYPE html>
<html>
<head>
    <title>Jack of All Trades</title>
</head>
<body>
<table border="1">
{% for element in data %}
    <tr>
    <td><p>column 1 </p></td>
    <td><p>column 2 </p></td>
    <td><p>column 3 </p></td>
    <td><p>column 4 </p></td>
    <td><p>column 5 </p></td>
    </tr>
{% endfor %}
</tr>
</table>
</body>
</html>

Assuming data has 5 elements it would produce something like this:

enter image description here

Answered By: K DawG

This worked better for me (divisibleby: n, n = number of columns):

          <form enctype="multipart/form-data" method="POST">
                {% csrf_token %}
                {% for field in form %}
                    {{ field.label }} {{ field }}
                    {% if forloop.counter|divisibleby:"2" %}
                        <br>
                    {% endif %}
                {% endfor %}
                <input type="submit" value="Continue" />
            </form>   
Answered By: j4n7

I use bootstrap 4 and form tag name is ’employee_in’. There is 6 input fields in each of the two columns (fixed, anyone else knows how to make it automatic?) best I can do so far, hope it helps

  <form enctype="multipart/form-data" method="post">
    {% csrf_token %}
    <div class="container-fluid">
      <div class="row">
        <div class="col-lg-6">
          <table class = 'table table-hover'>
            {% for my_divider in employee_in %}
              {% if forloop.counter <= 6 %}
                <tr>
                  <td>{{ my_divider.label }}</td>
                  <td>{{ my_divider }}</td>
                </tr>
              {% endif %}
            {% endfor %}
          </table>
        </div>
        <div class="col-lg-6">
          <table class = 'table table-hover'>
            {% for my_divider in employee_in %}
              {% if forloop.counter > 6 %}
                <tr>
                  <td>{{ my_divider.label }}</td>
                  <td>{{my_divider}}</td>
                </tr>
              {% endif %}
            {% endfor %}
          </table>
        </div>
      </div>
    <input type="submit" class = 'btn btn-secondary' value="Submit">
    </div>
  </form>
Answered By: Nelson Yan
<form method="POST">
{% csrf_token %}
<table>
    {% for field in form %}
        <tr>
            <td>{{ field.label}}</td>
            <td>{{ field }}</td>
        </tr>
    {% endfor %}
</table>
<button type="submit" class="btn btn-primary">Submit</button>
Answered By: Naseem

Another option to consider in newer versions of Django is to use Reusable form templates to create a form template to call as {{ form.as_td }}, just like you would call {{ form.as_table }} in your template.

This has a few nice features:

  • A FormSet with each form wrapped in a <tr> but fields wrapped in <td> can coexist with other nice add-ons like django-dynamic-formset
  • This method can be used for other elements your might want to render forms with

Steps:

  1. Create a RenderMixin that implements as as_td() method, to be called as {{ form.as_td }} in your template
from django.forms.utils import RenderableMixin

class ColumnRenderableFormMixin(RenderableMixin):
  def as_td(self):
    """Render as <td> elements excluding the surrounding <table> tag."""
    return self.render(self.template_name_td)
  1. Create a reusable template in your app templates directory (or other suitable directory)
{% for field, errors in fields %}
  <td>
    {{ errors }}
    {{ field }}
  </td>
{% endfor %}
  1. Add the custom mixin to your form, and specify the td.html template file path in the template_name_td class variable:
class SomeForm(ModelForm, ColumnRenderableFormMixin):
  template_name_td = "someapp/td.html"
  1. In your view’s template, render the form with {{ form.as_td }}.
  • If you’re using a formset this would look like the following:
<table class="table">
{% for form in formset %}
  <tr>
    {{ form.as_td }}
  </tr>
{% endfor %}
</table>
Answered By: modulus0