Django display limited images in grid row

Question:

As mentioned in the title. Is it possible to display a specific number of photos in a particular grid-container? For example, a maximum of 3 columns with a card in the row using a loop?
I was able to achieve the effect of displaying all the photos from the defined model,but I don’t know how to set the limit.

Below I present fragments of the code responsible for displaying the created model

forms.py

class ProductsForm(forms.ModelForm):
class Meta:
    model = Product
    fields = ('name', 'description', 'image', 'file_type')

models.py

class Product(models.Model):
name = models.CharField(max_length=20, default='')
description = models.CharField(max_length=100, default='')
file_type = models.CharField(max_length=256, choices=[('image', 'image'), ('thumbnail', 'thumbnail')], default='')

image = models.ImageField(upload_to='products', default='')

def __str__(self):
    return self.name

views.py

def gallery(request):
image = Product.objects.filter(file_type='image')
thumbnail = Product.objects.filter(file_type='thumbnail')
return render(request, 'products/fruits.html', {'img': image, 'thumb': thumbnail})

fruits.html

<!DOCTYPE html>
{% load staticfiles %}
{% load thumbnail %}
{% block body_block %}

<div class="grid-container">
    <div class="card-deck">


        {% for i in thumb %}
            {% thumbnail i.image "150x150" crop="center" as im %}

                <!-- Card -->
                <div class="card mb-4">

                    <!--Card image-->
                    <div class="view overlay">

                        <img src="{{ im.url }}"
                             alt="Card image cap">
                        <a href="#!">
                            <div class="mask rgba-white-slight"></div>
                        </a>
                    </div>

                    <!--Card content-->
                    <div class="card-body">

                        <!--Title-->
                        <h4 class="card-title">Card title</h4>
                        <!--Text-->
                        <p class="card-text">Some quick example text to build on the card title and make up
                            the
                            bulk
                            of
                            the
                            card's
                            content.</p>
                        <!-- Provides extra visual weight and identifies the primary action in a set of buttons -->
                        <button type="button" class="btn btn-light-blue btn-md">Read more</button>

                    </div>

                </div>

            {% endthumbnail %}
        {% endfor %}
    </div>

</div>
{% endblock %}
Asked By: marci

||

Answers:

The build-in Django filter divisibleby may work, inside your loop, you check whether the iteration is divisible by (in your case) 3, then you break the row to jump to another one:

{% for i in thumb %}
    {% if forloop.counter|divisibleby:3 %}
         ----------
    {% endif %}
{% endfor %}
Answered By: Lemayzeur

I was able to get what you want to do by creating a list of lists of images in the view, then send this list to the HTML template and display it with two loops. The advantage of this approach is that you can control the number of columns by changing one variable. Each element of the main list contains X number of columns.

The idea is to send a list like the one represented below (more or less)

photos_list = [[photo1, photo2, … photoN], [photo1, photo2, … photoN]]

the view code is:

def index(request):
    photos = Photo.objects.all()
    counter = -1
    columns_qty = 5 # << Just change this number for the columns you want
    photos_row = []
    photos_list = []
    for photo in photos:
        counter += 1
        if counter < columns_qty:
            photos_row.append(photo)
        else:
            photos_list.append(photos_row)
            photos_row = []
            counter = -1
    context = {'photos_list': photos_list}
    return render(request, 'photos/index.html', context)

the model code is:

class Photo(models.Model):
    file_name = models.CharField(max_length= 250)
    original_path = models.CharField(max_length=250)
    saved_path = models.CharField(max_length=250)
    file_size = models.IntegerField(null=True)
    file_created = models.DateTimeField(null=True)
    file_last_modified = models.DateTimeField(null=True)
    loaded_datetime = models.DateTimeField(default=timezone.now())
    def __str__(self):
        return self.file_name

and the html template code is:

{% extends 'photos/base.html' %}
{% load static %}

{% block content %}

<table>
    {% for photo_row in photos_list %}
    <tr>
        {% for photo_col in photo_row %}
            <td><img src="{% static photo_col.file_name %}" width="300px"
             height="auto"></td>
        {% endfor %}
    </tr>
    {% endfor %}
</table>

{% endblock %}

I hope this helps!

Answered By: Noah Random
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.