Django Image Gallery Website

In this tutorial, we are going to be Building a Django Image Gallery Website. This will accept a user-submitted picture, and then host it online.

You must be wondering why one would want to to have an image gallery website, so I have listed few reasons:

  1. You can easily share images with anyone.
  2. Having an online gallery that simplifies the process of posting on social media using automation.
  3. Archiving images that you may always retrieve in future.
  4. In case you want to be like Pixabay.

An open source code is available on GitHub here:

Building a Django Image Gallery Website
Django Image Gallery Website

We will focus on the following topics in this tutorial:

  • Getting a front-end template for our gallery website
  • Building our Models
  • Create the page for our image category
  • Create the detailed page for the image

Front-End Templates

For every tutorial that we have, we always try to use open source codes. We do this so that you won’t be required to make any purchases. We do not focus on designing templates from scratch, and it’s not compulsory to use the templates we use. You can use any other template you like.

Template 1: For the Category Page

An ideal example for this was the Bootstrap album: https://getbootstrap.com/docs/5.0/examples/album/

You may add photographs to a list with a title at the top of the page. This article is mainly based on that.

Template 2: Front Page

Visit this Link

Using the Bootstrap blog landing page, we just left our category list and website title at the top of the page and removed everything else.

Building a Django based App

This step is very crucial, but for the purpose of cutting this tutorial short, we will assume that you have a Django app, ready to use. If not, check out our previous tutorial on how to to build a Django app from scratch.

Further information can be found in our Skolo Online – Django documentation:

Models for Django Image Gallery Website

Any suggestions for a better model structure for such a website would be greatly appreciated. The Models are required for a Django image gallery, so we will use the following:

First Model: Image Category

Information about categories, data, and instances will all be stored in the first model. All images are organised by categories. We need to separate all our images into categories. For instance, (a) Outdoor, (b) Office, and (c) Park. This will depend on the purpose of your website.

We constructed a model for this because we don’t want these categories to be hardcoded into the app. Therefore we would rather make them dynamic, so that they can be added or removed as needed in the future.

Only a title variable is required for the category.

Second Model: Image Model

Image model has the title and the image that was uploaded as variables. The images we will upload in our scenario will be of three types:

Firstly, a landscape image. Secondly, a square image. Lastly a portrait image. These might be necessary since different social media sites take different image dimensions, and we will re-size the images and upload them.

from django.db import models
from django.template.defaultfilters import slugify
from django_resized import ResizedImageField
from django.utils import timezone
from uuid import uuid4
from django.urls import reverse
class Category(models.Model):
    title = models.CharField(null=True, blank=True, max_length=200)
    #Utility Variable
    uniqueId = models.CharField(null=True, blank=True, max_length=100)
    slug = models.SlugField(max_length=500, unique=True, blank=True, null=True)
    date_created = models.DateTimeField(blank=True, null=True)
    last_updated = models.DateTimeField(blank=True, null=True)
    def __str__(self):
        return '{} {}'.format(self.title, self.uniqueId)
    def get_absolute_url(self):
        return reverse('category-detail', kwargs={'slug': self.slug})
    def save(self, *args, **kwargs):
        if self.date_created is None:
            self.date_created = timezone.localtime(timezone.now())
        if self.uniqueId is None:
            self.uniqueId = str(uuid4()).split('-')[4]
            self.slug = slugify('{} {}'.format(self.title, self.uniqueId))
        self.slug = slugify('{} {}'.format(self.title, self.uniqueId))
        self.last_updated = timezone.localtime(timezone.now())
        super(Category, self).save(*args, **kwargs)
class Image(models.Model):
    description = models.TextField(null=True, blank=True)
    altText = models.TextField(null=True, blank=True)
    hashtags = models.CharField(null=True, blank=True, max_length=300)
    ##ImageFields
    squareImage = ResizedImageField(size=[1000, 1000], crop=['middle', 'center'], default='default_square.jpg', upload_to='square')
    landImage = ResizedImageField(size=[2878, 1618], crop=['middle', 'center'], default='default_land.jpg', upload_to='landscape')
    tallImage = ResizedImageField(size=[1618, 2878], crop=['middle', 'center'], default='default_tall.jpg', upload_to='tall')
    #Utility Variable
    uniqueId = models.CharField(null=True, blank=True, max_length=100)
    slug = models.SlugField(max_length=500, unique=True, blank=True, null=True)
    date_created = models.DateTimeField(blank=True, null=True)
    last_updated = models.DateTimeField(blank=True, null=True)
    def __str__(self):
        return '{} {}'.format(self.category.title, self.uniqueId)


    def get_absolute_url(self):
        return reverse('image-detail', kwargs={'slug': self.slug})
    def save(self, *args, **kwargs):
        if self.date_created is None:
            self.date_created = timezone.localtime(timezone.now())
        if self.uniqueId is None:
            self.uniqueId = str(uuid4()).split('-')[4]
            self.slug = slugify('{} {}'.format(self.category.title, self.uniqueId))
        self.slug = slugify('{} {}'.format(self.category.title, self.uniqueId))
        self.last_updated = timezone.localtime(timezone.now())
        super(Image, self).save(*args, **kwargs)

Django Image Re-sizing

We will use an image resizing package from Django to resize our images. Here is the URL to download it: https://pypi.org/project/django-resized/

Create the page for our image category

Upon clicking a link for a certain category on the front page, the user will be taken to this view. At this point we will get the link clicked by the user, so due to the slug that is available, we now know the category.

For additional information regarding the routing process and how we use slugs to route to the detailed page, please watch the video tutorial.

These views will be function-based, and they will look something like this:

def categoryPage(request, slug):

    category = Category.objects.get(slug=slug)
    images = Image.objects.filter(category=category).order_by('-date_created')[:6]
    for x in images:
        x.shortDescription = x.description[:130]

    context = {}
    context['images'] = images
    context['category'] = category

    return render(request, 'main/category.html', context)

The following are the responsibilities of this function:

  • Use the slug to retrieve the instance that belongs to the category that the user have selected.
  • Obtain all images associated with the category, limit them to six images and sort them according to the date_created variable
  • Include a field named ‘shortened description’
  • Provide the data to the front-end template

Create the detailed page for the image

Each uploaded image is displayed with a description on the detailed image page. The user will be able to reach it by clicking the image on the category page.

The view function:

def imageDetailPage(request, slug1, slug2):

    category = Category.objects.get(slug=slug1)
    image = Image.objects.get(slug=slug2)

    context = {}
    context['category'] = category
    context['image'] = image

    return render(request, 'main/image.html', context)

There is a lot of things to cover and we cannot include them all in an article, for a detailed information, check out our YouTube tutorial video. It covers everything including thorough explanation on everything.

Django Image Gallery Website

Leave a Reply

Your email address will not be published.

Subscribe to our mailing list

And get this 💃💃 Free😀 eBook !

Holler Box