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.
- Clone a local copy of this repository.
- Install the latest stable version of Python 3.10 and the packages in the requirements.txt file, preferably using a virtual environment (e.g. using venv).
- Rename the secrets_template.py file to
secrets.py
and assign a secret key string to theKEY
variable, as detailed in Django's documentation. - Navigate into the outer
photo_gallery
directory (which containsmanage.py
) in your chosen command-line interface, which is where you should run all of the following commands, and activate your virtual environment if applicable. - Set up the project as detailed in Django's official tutorial, skipping the project and app creation/coding steps (as these already exist within the cloned repository). Specifically, this includes reviewing/adjusting the project settings, applying the database migrations (creating/modifying your local database tables) using
python manage.py migrate
, and creating an admin site user (login details) usingpython manage.py createsuperuser
. - Run the test suite using
python manage.py test
; if any tests fail, check that you've followed all of the instructions correctly and then raise an issue if you're still encountering problems. - Run the application locally using
python manage.py runserver
. - There won't be much to see at this point, so add some placeholder data (photos, collections etc.) via the Django admin site or programmatically, as detailed in Django's official tutorial. From there, you can make any adjustments to the project code as desired.
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 major updates/features planned and I'm not looking for any substantial contributions (but you're welcome to fork your own version).
However, I plan to maintain the project by periodically upgrading to newer (actively supported) versions of Python/Django/Bootstrap/other packages and fixing any significant bugs.