1

I'm working on a project using Python(3.7) and Django(2.2) in which I have implemented two models ItemModel and Images so every item will have multiple images and added item into the images model and add a related_name but when I try to access these images in Django template it's not providing any information regarding those images.

Here are my models: From models.py:

class ItemModel(models.Model):
    stock_number = models.IntegerField(blank=False)
    title = models.CharField(max_length=255, blank=False)
    price = models.IntegerField(blank=False)
    description = models.TextField(max_length=1000)
    condition = models.CharField(max_length=255, choices=COND_CHOICES, blank=False)
    model = models.CharField(max_length=255)
    dimensions = models.CharField(max_length=255)
    make = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title


class Images(models.Model):
    item = models.ForeignKey(ItemModel, on_delete=models.CASCADE, related_name='images')
    image = models.ImageField(upload_to=images_directory_path)

Update: Here's the function i'm using to rename images:

def images_directory_path(instance, filename):
    return '/'.join(['images', str(instance.item.id), str(uuid.uuid4().hex + ".png")])

And here's I'm trying to access these images for an item in the template:

{% for img in item.images.all %}
    {% if forloop.first %}
        <td> {{ item.images.first.name }}</td>
    {% endif %}
{% endfor %}

Here's the view:

From views.py:

class Inventory(View, LoginRequiredMixin):
    def get(self, request):
        items = None
        try:
            items = ItemModel.objects.all()
        except ItemModel.DoesNotExist:
            return redirect('home')

        return render(request, 'app/inventory.html', {'all_items': items})

what can be wrong here?

Abdul Rehman
  • 5,326
  • 9
  • 77
  • 150

4 Answers4

1

Looks like you just need

{% for img in item.images.all %}
    {% if forloop.first %}
        <td> <img src="{{ img.image.url }}"/> </td>
    {% endif %}
{% endfor %}
Rakesh
  • 81,458
  • 17
  • 76
  • 113
0

You do not need the for loop

<td> {{ item.images.first.name }}</td>

Will do, since it will return the first image (if one exists) without having to loop over every image

Iain Shelvington
  • 31,030
  • 3
  • 31
  • 50
0

in addition to Rakesh answer, you may find it necessary to check if the image exists before retrieving it by adding another if statement.

In your template do this;

{% for img in item.images.all %}
   {% if forloop.first %}
    {# add this if statement to check if the image exists in the table #}
       {% if img.image %}     
         <td><img src="{{ img.image.url }}"/></td>
       {% endif %}
   {% endif %}
 {% endfor %}
Mugoya Dihfahsih
  • 425
  • 3
  • 11
0

NEVER access related name like below example:

{{ item.images.first.name }}

This will cause a new fresh query to DB, instead you should use it like this:

{{ item.images.all.0.name }}

This does not need a forloop, also this will be prefetched from original query in view, just add .prefetch_related() in the original query in view.

Yousef Alm
  • 238
  • 1
  • 8