Home > Mobile >  How do I access the data from inside a nested for loop
How do I access the data from inside a nested for loop

Time:11-01

I want to do something like below in html where multiple "spots" are displayed, and within each spot the "links" associated to each specific spot is displayed.

How would I write the logic to display the specific links for each spot?

html

{% for spot in spots %}
    <div>
      <h2>{{ spot.title }}</h2>
    </div>
    {% for link in links %}
    <div>
      <h3>{{ link.url }}</h3>
    </div>
    {% endfor %}
{% endfor %}

My models are as below. SpotLinks is the intermediate table for Links and Spots table.

models.py

class Spots(models.Model):
    title = models.CharField(max_length=155)
    slug = models.SlugField(unique=True, max_length=155)


class Links(models.Model):
    title = models.CharField(unique=True, max_length=155, blank=True)
    url = models.CharField(max_length=75, blank=True)


class SpotLinks(models.Model):
    link = models.ForeignKey('Links', models.DO_NOTHING)
    spot = models.ForeignKey('Spots', models.DO_NOTHING)


class Articles(models.Model):
    title = models.CharField(max_length=155)
    slug = models.SlugField(unique=True, max_length=155)
    summary = models.TextField(blank=True, null=True)


class ArticleSpots(models.Model):
    article = models.ForeignKey('Articles', models.DO_NOTHING)
    spot = models.ForeignKey('Spots', models.DO_NOTHING)

I tried links = Links.objects.filter(spotlinks__spot=spots) in views.py but because spots has multiple spots in it it doesn't get filtered.

Will the logic be written in the views.py or as django templates in the html file?

Im new to web development so any direction would help. Thanks!

views.py

def article(request, slug):
    article = get_object_or_404(Articles, slug=slug)
    spots = Spots.objects.filter(articlespots__article=article).distinct()

    links = Links.objects.filter(spotlinks__spot=spots)

    context = {
        'spots': spots,
        'article': article,
        'links': links}

    return render(request, 'articletemplate.html', context)

CodePudding user response:

You need to add one foreign field to Links model to reference spot, so Links model will be:

class Links(models.Model):
    title = models.CharField(unique=True, max_length=155, blank=True)
    url = models.CharField(max_length=75, blank=True)
    spot = models.ForeignKey(Spots, on_delete=models.CASCADE, related_name="links")

thereby, you can get the links for each spots by:

from django.shortcuts import get_object_or_404
spot = get_object_or_404(Spots, title="choose the the title") # you can filter it in your preferred way
links = spot.links.all()

Then, in context; you don't need to send links at all, instead you can iterate in html in this way:

{% for spot in spots %}
    <div>
      <h2>{{ spot.title }}</h2>
    </div>
    {% for link in spot.links %}
    <div>
      <h3>{{ link.url }}</h3>
    </div>
    {% endfor %}
{% endfor %}

CodePudding user response:

To access the related objects, use the related manager.

In this case, the related manager is spot.spotlinks_set.

{% for spot in spots %}
    <div>
      <h2>{{ spot.title }}</h2>
    </div>
    <!-- {% for link in links %} -->             <!-- Replace this -->
    {% for spotlink in spot.spotlinks_set.all %} <!-- with this    -->
    <div>
      <!-- <h3>{{ link.url }}</h3> --> <!-- Replace this -->
      <h3>{{ spotlink.link.url }}</h3> <!-- with this    -->
    </div>
    {% endfor %}
{% endfor %}

Reference: https://docs.djangoproject.com/en/3.2/ref/models/relations/

  • Related