Search code examples
pythonhtmldjangosyntax-errorone-to-many

How to parse the many values of one-to-many relationship into HTML template in Django?


I have a one-to-many relationship in Django as such:

class Listing(models.Model):
    title = models.CharField(max_length=60)

class Images(models.Model):
    listings = models.ForeignKey(Listing, on_delete=models.CASCADE)
    image_urls = models.URLField(max_length = 200)

I have the following view defined:

from .models import Listing, Images

def index(request):
    All_Listings = Listing.objects.filter(isActive=True)
    return render(request, "index.html", {
        "All_Listings": All_Listings,
        "Images" : Images
    })

Now for each listing I want to show all related images in my HTML. I have tried to do the following:

{% extends "layout.html" %}

{% block body %}
{% for listing in All_Listings %}
<h2>{{ list(Images.objects.filter(listings_id=2))  }}<h2>
{% endfor%}
{% endblock %}
(If this works, than later on I will replace 2 with listing.id)

This returns the following error:

Exception Type:     TemplateSyntaxError
Exception Value:    Could not parse the remainder: '(Images.objects.filter(listings_id=2))' from 'list(Images.objects.filter(listings_id=2))'

However, when I run this from the terminal it works:

>>> list(Images.objects.filter(listings_id=2))
[<Images: https://www.kettererkunst.com/still/kunst/pic570/531/422000352-4.jpg>, <Images: https://www.kettererkunst.com/still/kunst/pic570/531/422000352-1.jpg>]

How should I approach this?


Solution

  • You can create the @property image in the Listing class, and query all the related Images in it.

    class Listing(models.Model):
        title = models.CharField(max_length=60)
      
        @property
        def images(self):
            return Images.objects.filter(listings=self)
    
    class Images(models.Model):
        listings = models.ForeignKey(Listing, on_delete=models.CASCADE)
        image_urls = models.URLField(max_length = 200)
    

    And then call listing.images in the template:

    {% for listing in All_Listings %}
       {%for image in listening.images%}
          {{ image }}
       {% endfor%}
    {% endfor%}