Home > Mobile >  How to iteratively render the first X fields in a Django form
How to iteratively render the first X fields in a Django form

Time:04-30

I'm rendering a form in a Django html template by using a for loop and iterating over the fields. I want to add some sections & headers inside my form, so is there a way to 'slice' the form fields or otherwise iteratively display only a subsection of fields?

Something like

{% for field in form.slice(0, 5) %}
<!-- render first 5 fields -->
<h2>Section 2</h2>
<p>Some text about next section</p>
{% for field in form.slice(5, 10) %}
<!-- render the next 5, etc. -->

I know the worst case answer is to render each field manually, but it's a VERY long form. Here's my existing form code.

      {% for field in form %}
      <div >
        <label  for="{{field.id_for_label}}">
          {{field.label}}
        </label>
        <div >{{field}}</div>
        {% if field.help_text %}
        <p >{{field.help_text}}</p>
        {% endif %}
        <ul >
          {% for error in field.errors %}
          <li >{{error}}</li>
          {% endfor %}
        </ul>
      </div>
      {% endfor %}

CodePudding user response:

You can make use of Django forloop.counter0 or forloop.counter variables. The first one which keeps track of the iteration inside the loop starting with index 0 and the second one indexes iterations starting with 1 (see the bottom of this section see the bottom of this section https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#for for more):

    {% for field in form %}     
      {% if forloop.counter0 == 5 %}
        <h2>Section 2</h2>
        <p>Some text about section 2</p>
      {% elif forloop.counter0 == 8 %}
        <h2>Section 3</h2>
        <p>Some text about section 3</p>
      {% endif %}
      <div >
        <label  for="{{field.id_for_label}}">
          {{field.label}}
        </label>
        <div >{{field}}</div>
        {% if field.help_text %}
        <p >{{field.help_text}}</p>
        {% endif %}
        <ul >
          {% for error in field.errors %}
          <li >{{error}}</li>
          {% endfor %}
        </ul>
      </div>
    {% endfor %}

You would still have to manually check for the values. If you want for example to add section content in a way you can iterate the content every 5 fields you can take advantage of divisibleby and Django-Mathfilters to divide:

    {% for field in form %}     
      {% if forloop.counter0|divisibleby:5 %}
        <h2>Section {{ forloop.counter0|div:5}}</h2>
        <p>Some text about section {{ forloop.counter0|div:5}}</p>
      {% endif %}
      <div >
        <label  for="{{field.id_for_label}}">
          {{field.label}}
        </label>
        <div >{{field}}</div>
        {% if field.help_text %}
        <p >{{field.help_text}}</p>
        {% endif %}
        <ul >
          {% for error in field.errors %}
          <li >{{error}}</li>
          {% endfor %}
        </ul>
      </div>
    {% endfor %}

For more references you can see Modulus % in Django template to know about divisibleby and Is there a filter for divide for Django Template? to get some other methods on how to divide numbers in your Django template!

  • Related