Photography Website

My first Django app

Brief: Create a simple photography website to host my own photos using Django and AWS resources.

Core Skills: Server-side optimisations, SQLite database administration, Python/Django, Web Development, HTML/CSS.


This was my first Attempt at my personal website. The goal was to learn the basics of the Django framework and HTML/CSS. I also needed a reason to learn a bit about data, storing persistent data, and database version control. I have a surplus of my own photos and nowhere to put them except Instagram so I decided it would be a good learning experience and maybe something I could use to share my photography.

Database Selection

I considered a few options for databases on my website. I wanted something that would be a useful learning experience and also be simple to set up, manage, and maintain. I looked into Turso, a LibSQL SaaS but it was a bit too simple. The whole set up is done for you and I wouldn't learn anything if someone else did it all for me. I was already familiar with PostgreSQL from uni and a few work projects, but I also knew that the overhead of setting up and managing a whole separate server would become a chore. Not to mention version control would be exponentially more exhausting.
I settled on a simple SQLite single-file database. I make changes to the database locally when developing the website. Then when I'm ready, I commit those changes to git and the database is copied to the production website. As I am the only "user" of my website, this has the advantage of keeping many aspects of developing and running the website simple while having no drawbacks.

S3 Buckets for Photo Storage

Storing images in the database is possible, It's not the most efficient or cheapest option. The database is hosted on a single micro EC2 instance which means processing power is budgeted and I can't waste it serving huge photo files from a file database.
Instead, I chose to configure an S3 Bucket to publicly host my photos. The database holds metadata corresponding to the photos in the bucket including the URL. All I had to do was use Django's built-in ORM to query the database for the URL of any photo I'm after and load it to the webpage.

A screenshot of my photography website Photography website as of April 2025

Optimising photo load times

I soon found that having a webpage concurrently load eight 4K images regardless of where they were coming from would be a slow process. Anyone coming to my website might not have the patience for that. So using the Python Pillow Library, I modified the Photo model I had created in my website to automatically create a downsized (720p) image upon uploading a new image.
When the website requests a photo, it will aways get the smaller photo, except when the full-detail page is requested.

Full-size image loaded from S3 A full size photo detail page as seen on a mobile phone or tablet

Dynamic Static Storage

I configured Django's Storages backend to default to S3 when it's in production and to use local files when in debug mode. This prevents excessive calls to the S3 Bucket when developing the website locally, as oftentimes we might reload page after page. The outcome is drastically lowering the chance that I'll go over the download limit and start getting charged for every time someone accesses my website.

I still update my photography website occasionally. Adding photos and tweaking the layout. Feel free to check out the photos and download the full size images if you like (non-commercial use only).


get in touch