Home > OS >  Best way to divide a template by sections? (multiple queried for loops?) (Django)
Best way to divide a template by sections? (multiple queried for loops?) (Django)

Time:06-24

I have a model which lists projects - one of these fields records a projects' state as foreign key to a status model.

I would like to have a view where the projects are listed, however are divided by status, for example.

    <h1 >Projects</h1>

 <h2>Projects with a Status of 1<h2>
{% for projects in projects %}

<h3>> {{ projects.name_title_working }}</h3>
<p>> {{ projects.fk_state }}</p>
<p>> {{ projects.genre }}
<p>> {{ projects.d_conceived }}

{% endfor %}

<h2>Projects with a Status of 2<h2>
{for loop}

<h2>Projects with a Status of 3<h2>
{for loop}

etc.

How would i query at the template level like this, or would there need to be additional steps where the querying is done at a lower level?

CodePudding user response:

Assuming your models look something like this:

from django.db import models


Project(models.Model):
    name = models.CharField(max_length=50)
    status = models.ForeignKey(Status, on_delete=models.SET_NULL, null=True)

Status(models.Model):
    state_id = models.IntegerField()

You could "filter" the relevant projects with an if-condition in the template:

<h1 >Projects</h1>

<h2>Projects with a Status of 1<h2>
{% for project in projects %}
    {% if project.status.state_id == 1 %}

    <h3>{{ project.name }}</h3>
    <p>{{ project.status }}</p>

    {% endif %}
{% endfor %}

<h2>Projects with a Status of 2<h2>
{% for project in projects %}
    {% if project.status.state_id == 2 %}

    <h3>{{ project.name }}</h3>
    <p>{{ project.status }}</p>

    {% endif %}
{% endfor %}

[...]

If you also have a queryset of all the possible states available as a template variable, you could even reduce the amount of code you write by using a nested loop:

<h1 >Projects</h1>

{% for s in status %}
    <h2>Projects with a Status of {{ s.state_id }}<h2>
    {% for project in projects %}
        {% if project.status == s %}
        
        <h3>{{ project.name }}</h3>
        <p>{{ project.status }}</p>

        {% endif %}
    {% endfor %}
{% endfor %}

I think this should work fine as long as the number of projects and states is relatively small. If you are dealing with a very large number of projects and states, these solutions might be too inefficient.

CodePudding user response:

The builtin template tag regroup does what you want.

{% regroup projects by status as status_list %}
{% for status in status_list %}
<h2>Project of status {{ status.grouper }}</h2>
<ul>
  {% for project in status.list %}
     <li>{{ project.name }}</li>
  {% endfor %}
</ul>
{% endfor %}
  • Related