2

I'm trying to loop through different Zones and then show the items which are part of this zone

Zone is a model, has a name and a ForeignKey. Planche is a model which has Zone as ForeignKey.

I'm looping through zones to display each zone. In that loop I'm looping all Planches and would like to display only the ones that have Zone as a ForeignKey.

class Zones(models.Model):
    name = models.CharField(max_length=30)
    genre = models.ForeignKey(ZoneTypes, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class Planche(models.Model):
    pzone = models.ForeignKey(Zones, on_delete=models.CASCADE)
    ref = models.CharField(max_length=5, default="1")
    length = models.IntegerField()
    width = models.IntegerField()
    orientation = models.CharField(max_length=30)

    def __str__(self):
        return self.ref

Template

<div>
     <h1><a href="/">My list of planches</a></h1>
</div>
{% for z in zones %}
    <div>
        <h2><a href="/zone/{{ z.name }}">Zone name: {{ z.name }}</a></h2>
        {% for p in planches %}
        {% if p.pzone == z.name }
        <h1><a href="planche/{{ planche.ref }}">Ref: {{ p.ref }}</a></h1>
        <p>Length: {{ p.length }} - Width: {{ p.width }}</p>
        <p>Orientation: {{ p.orientation }}
        {% endif %}
        {% endfor %}
    </div>
{% endfor %}

{% if p.pzone = z.name %} returns False, They both return the same string if I just display them {{ p.pzone }} and {{ z.name }} but I guess they aren't the same data type. I tried converting them to strings in a {% with %} statement but I keep failing

Gradient
  • 135
  • 1
  • 8

2 Answers2

1

I'm assuming you want to display all the planches for each zone. You can use the related_name on the ForeignKey to access to items referencing the current object. You did not set any related name there, so it's the default one: planche_set.

<div>
     <h1><a href="/">My list of planches</a></h1>
</div>
{% for z in zones %}
    <div>
        <h2><a href="/zone/{{ z.name }}">Zone name: {{ z.name }}</a></h2>
        {% for p in z.planche_set.all %}
        <h1><a href="planche/{{ planche.ref }}">Ref: {{ p.ref }}</a></h1>
        <p>Length: {{ p.length }} - Width: {{ p.width }}</p>
        <p>Orientation: {{ p.orientation }}
        {% endfor %}
    </div>
{% endfor %}

Be aware that method will execute N+1 queries (One to select your zones then one query per zone to retrieve the planches of each zone) unless you add prefetch_related('planche') in the view where your select your zones.

References:

Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
1

If you want to display Planches for every Zones, you can write the second loop like this:

<div>
  <h1><a href="/">My list of planches</a></h1>
</div>
{% for z in zones %}
    <div>
        <h2><a href="/zone/{{ z.name }}">Zone name: {{ z.name }}</a></h2>
        {% for p in z.planche_set.all %}
        <h1><a href="planche/{{ planche.ref }}">Ref: {{ p.ref }}</a></h1>
        <p>Length: {{ p.length }} - Width: {{ p.width }}</p>
        <p>Orientation: {{ p.orientation }}
        {% endif %}
        {% endfor %}
    </div>
{% endfor %}

Here is example from another post: Django foreign key relation in template

J_R_
  • 21
  • 2