Search code examples
djangodjango-templatesdjango-template-filters

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


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 class="main_title">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?


Solution

  • 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 class="main_title">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 class="main_title">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.