A photo gallery website built using Django 4 and Bootstrap 5. Take a look: https://cmastris.eu.pythonanywhere.com/.
Photo detail pages are dynamically populated based on Photo model objects, which are fully editable via the Django admin site. This includes:
- The photo image (resized to desktop and mobile versions during upload, for faster loading)
- Title, location, date, and description content
- A list of Collections that contain the Photo (if applicable)
Check out the code: Photo and Collection models; PhotoDetailView; photo detail template; URL config.
Photo listing pages are dynamically populated based on Photo and Collection model objects, which are fully editable via the Django admin site. More specifically, these include:
- The homepage: all published Photos
- Collections: all published Photos in the Collection (with Collection description content)
- Search results: all published Photos whose title, location, or description contains the search query
Listing pages are sorted by featured status and then by newest to oldest by default, while the homepage and collections can also be sorted by newest to oldest or vice versa. All listing pages feature dynamic paginated URLs and links.
Check out the code: Photo and Collection models; photo views; list template; collection template; search template; URL config.
Rather than being hardcoded, the primary site navigation menu is generated based on model objects that are editable via the Django admin site. This includes:
- The type, number, and order of navigation sections (top-level links or dropdowns)
- The number and order of links within a dropdown
- The text and URLs of sections and links
Check out the code: NavLink and NavSection models; navigation context processor; base template.
Contact functionality is implemented using a model so that all contact messages are viewable via the Django admin site and can then be marked as responded to and/or resolved. Optional email alert functionality is also implemented (refer to setup and deployment for configuration details).
Check out the code: ContactMessage model; contact views; contact template; contact success template; URL config.
Model objects can be created, edited, and deleted via the admin site, Django's simple content management system (CMS). Beyond the out-of-the-box implementation, model object listing and detail pages have been customised to provide useful data and functionality. For example:
- Photo listing and change pages include a photo thumbnail image
- Photo and Collection add pages auto-populate the URL slug field
- Collection and Country pages include associated Photo counts
- Photos and ContactMessages can be searched and filtered
- Help text is used to describe some (less obvious) model fields
Check out the code: Photo, Collection, and Country admin config; NavLink and NavSection admin config; ContactMessage admin config; Photo, Collection, and Country models; NavLink and NavSection models; ContactMessage model.
Fundamental search engine optimisation (SEO) best practices are met, including:
- Dynamically generated page titles, meta descriptions, and Open Graph content (based on Photo and Collection model data)
- Appropriately canonicalised URLs (including sorted and paginated listing pages)
- A dynamically generated XML sitemap
- A robots.txt file that prevents the crawling of search results pages
Note: this website is designed to be a personal portfolio that minimises the effort required to add/edit content. As such, some SEO-related content/tags (e.g. page titles) can't be edited specifically; however, model fields could be added and/or templates changed to support additional customisation.
Check out the code: template (HTML) files; XML sitemap config; robots.txt.
Important functionality that extends or modifies Django's code is validated via over 40 unit tests. Wider functionality and cross-device rendering has also been manually tested thoroughly.
Check out the code: photo tests; navigation menu tests; contact message tests.
If you're unfamiliar with Django, the official tutorial explains how to set up a new project.
As an overview, you'll need to clone a local copy of this repository, install the requirements, and run the database migrations using python manage.py migrate
from within the outer photo_gallery
directory that contains manage.py
. From there, you can run the application locally using python manage.py runserver
from within the same directory.
When you're ready to deploy a production (i.e. public) version of the website, be sure to read Django's deployment documentation (including the deployment checklist) to avoid security vulnerabilities and other issues.
For this project, the following deployment steps will also be necessary:
- Use prod_urls.py (which removes development-only media file serving) rather than urls.py
- Configure and use prod_settings.py (which ensures that project settings are safe and appropriate for production), referring to the settings documentation where needed, rather than settings.py
- Run a site name data migration (which is used to construct absolute URLs, e.g. in the XML sitemap and HTML tags) using the template and instructions in site_name_migration_template.py
- Change the robots.txt sitemap link to the correct URL (for simplicity, this doesn't use the site data in the previous step)
- Configure contact message email alerts (implemented in contact/views.py) via the email settings in prod_settings.py, if desired (otherwise, just check messages regularly via the Django admin site)
- Change the favicon if desired
Yes! A production version of the website which is populated with content (my own photos) can be found here: https://cmastris.eu.pythonanywhere.com/.
After completing the Django for Everybody Specialization on Coursera, I wanted to build upon my experience working with Django. (Showing off my photos was a bonus!)
Feel free to create an issue or open a new discussion.
There are no further updates/features planned and I'm not looking for contributions, but I'll be happy to fix any (significant) bugs.