This is my Django blog project. My blog focuses on the art of candle making, creating a cozy atmosphere, and finding balance through warmth and light. The project follows Djangoβs Model-View-Template (MVT) architecture and is deployed using Render.
This project is deployed on Render.
- Created a Render account and connected it to my GitHub account.
- Added a new Web Service in Render:
- Selected my Django project repository
django_blog_proj4from GitHub. - Set Python as the runtime environment.
- Chose the branch
main. - Configured the build and start commands:
- Build command:
pip install -r requirements.txt - Start command:
gunicorn django_blog.wsgi:application
- Build command:
- Selected my Django project repository
- Configured environment variables::
DEBUG=FalseSECRET_KEYset securely via Render environment settings.
- Configured static files:
- Added
STATIC_ROOT = BASE_DIR / 'staticfiles'insettings.py. - Used WhiteNoise for serving static files in production.
- Ran
python manage.py collectstaticlocally before deployment.
- Added
- Created
build.shin the project root to handle any additional setup Render needs during deployment. - Database setup:
- Development: Used SQLite during initial local testing.
- Production: Migrated to Neon PostgreSQL, a serverless database platform.
- Integrated the database using the dj-database_url package to parse the connection string from environment variables.
- Configured DATABASE_URL securely within Render's environment settings to connect the Django application to the Neon cluster.
- Deployed the project:
- Render built the project automatically
- Gunicorn served the WSGI application
- Live site: π https://django-blog-proj4.onrender.com
Initially, the project had a nested structure:
django_blog_proj4/django_blog_proj4/
This caused confusion during deployment.
Fix:
The unnecessary inner folder was removed, the project structure was flattened, and the app was redeployed successfully.
VS Code showed an import error for dj_database_url even though the package was installed.
Cause:
VS Code was using the wrong Python interpreter.
Fix:
Switched the interpreter to the correct .venv, after which the error was resolved.
After creating a superuser, logging into the Django admin panel on Render failed. Debugging steps:
- Verified that the superuser existed using Django shell
- Checked that database migrations were applied
- Confirmed model fields using: Post._meta.get_fields()
- Ensured correct database connection settings and environment variables on Render. Result: The issue was traced to database connection handling during deployment. After verifying migrations and database configuration, the admin access worked correctly.
After deploying the blog, published posts were not showing on the homepage, even though they existed in the local database.
Cause:
The fixture data (posts.json) had not been loaded into the production database.
Fix:
- Uploaded
posts.jsonto the server inblog/fixtures/. - Ran the management command on the server terminal:
python manage.py loaddata postsPosts loaded via fixtures initially had author_id values that did not correspond to the production superuser, causing them to appear as βunknownβ in the admin.
Fix:
- Used Django shell on the server to update the author for all posts.
- Confirmed that all posts now had the correct author and were fully visible in the admin.
After setting up the template inheritance, the home page failed with a TemplateDoesNotExist error, specifically unable to find base.html.
Cause: Django's template engine was only looking for templates inside individual app directories (APP_DIRS: True). Since base.html was located in a global templates/ folder at the project root, Django couldn't "see" it because the DIRS list in settings.py was empty.
Fix: - Updated TEMPLATES configuration in settings.py by adding BASE_DIR / 'templates' to the DIRS list.
- Verified that the global
templates/directory contains thebase.htmlfile. - This allowed Django to look for templates in both the global folder and app-specific folders.
While updating the Comment model (renaming fields and adjusting logic), a migration error occurred: "It is impossible to add a non-nullable field to comment without specifying a default."
Cause: Renaming fields (active to approved and comment_author to author) was interpreted by Django as adding new columns to a table that already contained data. Since these fields cannot be empty, Django required a default value for existing rows.
Fix: - Used the command line prompt to provide a one-off default value.
- Assigned the Superuser ID (
1) as the default for theauthorfield. - Successfully ran
makemigrations blogandmigrateto synchronize the database schema.
After implementing django-allauth, the registration page (/accounts/signup/) was functional but lacked the project's visual branding and layout.
Fix: - Created a custom directory structure: templates/account/signup.html.
- Implemented template inheritance by adding
{% extends "base.html" %}. - Customized the signup form using Bootstrap classes and specialized CSS for the
.btn-signupaction.
During the styling phase, updates made to style.css were not appearing during local testing.
Cause: Β
The project used WhiteNoise with CompressedManifestStaticFilesStorage, which aggressively caches static files. Additionally, the pre-compiled files in the staticfiles/ directory were overriding the fresh changes in the static/ folder.
Fix: Β
- Temporarily switched
STATICFILES_STORAGEtoStaticFilesStorageinsettings.pyto disable manifest-based caching during development. - Deleted the auto-generated
staticfiles/directory to force Django to collect fresh assets. - Used a "Hard Refresh" (
Ctrl + F5) in the browser to clear the local cache and load the latest styles.
During the implementation of the comment delete modal, the JavaScript console showed a ReferenceError: bootstrap is not defined.
Cause: The custom JavaScript file (comments.js) was being loaded before the Bootstrap library script in base.html. Since the script relied on Bootstrap's Modal component, it failed to execute.
Fix: Rearranged the script tags in base.html to ensure the Bootstrap bundle (JS) is loaded first, followed by the {% block extras %} containing the custom logic.
After adding JavaScript logic to the Edit and Delete buttons, clicking them resulted in no action, despite the code being correct.
Cause: The browser was caching an older, empty version of comments.js. Additionally, some HTML elements were missing specific IDs required by the JavaScript selectors.
Fix: - Added unique IDs to the comment form (id="commentForm") and the body textarea (id="id_body").
- Performed a "Hard Refresh" (
Ctrl + Shift + R) to force the browser to fetch the latest version of the static files.
Issue: After implementing the "Edit" function for comments, the page would scroll to the top, and the user had to manually find the form. Additionally, new JavaScript changes were not appearing in the browser.
Cause: - The JavaScript logic lacked a .focus() call.
- The browser was caching an older version of
comments.js, ignoring new code updates.
Fix: - Added commentText.focus() to the event listener in comments.js.
- Used Chrome DevTools (Sources tab) to verify the active code.
- Performed a "Hard Reload & Empty Cache" to force the browser to load the updated script.
Issue: Whenever a user tries to hard refresh the page, the JavaScript code is submitted twice.
Cause: This behavior is due to specific JavaScript implementations taken from Code Institute tutorials. The scripts are triggered in a way that causes a double execution during a forced browser reload.
Status & Future Goal: This remains a known bug for now. My goal for future development is to refactor the script initialization logic to ensure it only executes once, regardless of how the page is reloaded.
This project was developed using Agile principles. I used GitHub Projects to manage User Stories and prioritize tasks.
Tasks were categorized using the MoSCoW prioritization technique:
- Must Have: Critical core features (Authentication, CRUD for posts/comments).
- Should Have: Important but not vital features (Notifications, Drafts).
- Could Have: "Nice-to-have" features for future enhancement.
You can view my interactive Kanban board here: π Link to GitHub Project
- Python 3.12: The core programming language for backend logic.
- Django 4.2: The high-level Python web framework used for rapid development.
- HTML5 / CSS3: For structure and custom styling.
- JavaScript: Used for interactive components (modals, comment editing).
- Bootstrap 5: CSS framework for responsive design and UI components.
- PostgreSQL: Production-grade database hosted on Neon.
- WhiteNoise: Efficient static file serving for Python web apps.
- Git & GitHub: Version control and project management (Agile board).
- Render: Cloud platform for application deployment.
- Gunicorn: WSGI HTTP Server for production.
- VS Code: Integrated development environment.
- Chrome DevTools: Essential for debugging CSS and JavaScript.
- Rich Text Editing: Integrated
django-summernotefor bothPostandAboutmodels to allow professional content formatting. - Efficient Management: Added
list_display,list_filter, andsearch_fieldsto the admin panel for quick data filtering. - Automated Workflows: Configured
prepopulated_fieldsfor automatic slug generation and created a custom "Bulk Approve" action for comments.
- Cozy Branding: Developed a minimalist, warm-themed UI with a custom color palette (#351e89) designed to evoke a sense of peace and "spiritual" calm.
- Responsive Navigation: A clean, unified navigation bar across all pages, dynamically updating based on the user's authentication status (Login/Logout/Register).
- Interactive Blog Feed: Homepage features post previews with automated summaries (using
striptags) and organized pagination (6 posts per page).
- About App: A dedicated section with a custom model and view to share the personal story and mission of the Candle Therapy Blog.
- Community Interaction: Integrated a robust comment system where registered users can engage with posts, subject to admin approval for safety.
- Secure Authentication: Used
django-allauthto handle user registration and secure sign-in/sign-out processes. - Dynamic Content Delivery: Optimized template inheritance using a global
base.htmland managed static assets effectively for both development and production.
- Create: Authenticated users can leave comments on any blog post.
- Read: Comments are displayed in a clean, organized list below each post, with a clear status indicator for comments awaiting moderation.
- Update: Users can edit their own comments. The comment's status is automatically reset to "unapproved" after editing to ensure content safety.
- Delete: Users can remove their comments. A custom Bootstrap Modal confirmation step was implemented to prevent accidental deletions (Defensive Programming).
- Real-time UX: JavaScript is used to handle "Edit" and "Delete" actions instantly without page reloads, providing a modern and seamless user experience.
- Custom Candle Order: Add a "Build Your Own Candle" feature where users can customize their order by selecting size, scent, and wax type.
- Search Functionality: Implement a search bar to allow users to filter candle posts by keywords.
- Social Media Share Buttons: Add integration for users to share their favorite posts on Pinterest, Instagram, and Facebook.
- User Profiles: Create a dedicated profile page where users can manage their comments and account details.
- Newsletter Subscription: Improve a form for users to subscribe to email updates about new candle recipes and tips.
- Known Bug Refactoring: Address Bug 13 by optimizing JavaScript execution to prevent double submission during hard refreshes.
| Feature | Action | Expected Result | Status |
|---|---|---|---|
| Navigation | Clicked all links in navbar | All links redirect to correct pages | Pass |
| Authentication | Registered new user and logged in | User session starts, "Logged in as..." appears | Pass |
| CRUD: Create | Submitted a new comment on a post | Comment appears and stays "Waiting for approval" | Pass |
| CRUD: Update | Edited an existing comment | Comment body updates and status resets to unapproved | Pass |
| CRUD: Delete | Clicked delete and confirmed in modal | Comment is removed from the database | Pass |
| Admin Panel | Approved a comment via Admin | Comment becomes visible to all users | Pass |
| Responsiveness | Tested on mobile, tablet, and desktop | Layout adjusts correctly using Bootstrap grid | Pass |
I used the W3C HTML Validator to check the rendered HTML of all main pages by copying the source code from the browser. All pages passed with no errors.
| Page | Result | Screenshot |
|---|---|---|
| Home Page | Pass (No errors) | View |
| Post Detail | Pass (No errors) | View |
| About Page | Pass (No errors) | View |
| Login Page | Pass (No errors) | View |
Click to view HTML Validation Proofs
Click to view screenshots of the live project
The main stylesheet was validated using the W3C Jigsaw Validator.
- File:
static/css/style.css - Result: Pass (No errors found)
I have used the CI Python Linter to validate all custom Python files within the blog app. This ensures that the code follows standard Python formatting rules, making it clean, readable, and maintainable.
| File | Result | Screenshot |
|---|---|---|
| views.py | Pass (No errors) | View |
| models.py | Pass (No errors) | View |
| urls.py | Pass (No errors) | View |
| admin.py | Pass (No errors) | View |
Click to view PEP8 Validation Proofs
The application's design is crafted to evoke a "cozy" and "warm" atmosphere, perfectly matching the candle therapy theme.
The palette uses earthy, warm tones to create a sense of comfort:
- Primary Background:
#f6ede0(Soft Cream) β provides a warm, paper-like feel. - Navbar Background:
#5d4037(Deep Brown) β creates a strong, grounding header. - Primary Accents:
#351e89(Deep Indigo) β used for brand identity, links, and notification headers. - Action Buttons:
#d4a373(Warm Gold/Tan) β used for the signup and interactive elements to guide the user. - Text:
#554848(Muted Cocoa) β softer than pure black for a more organic look.
- Primary Font: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif. Chosen for its clean lines and excellent readability across all devices.
- Spacing: Cards use generous padding (
40px) and soft shadows to create a modern, "breathable" layout.
Before development, I created wireframes to plan the layout. These blueprints focused on a centered, distraction-free user experience.












