Blogging Platform is a Django-based web application that allows users to create, view, edit, and delete blog posts with images. It uses Django models to store blog information, views to handle user requests, and templates to display posts dynamically.
- New blog posts can be added through the Django Admin Panel, while the website provides options to view, edit, and delete existing posts.
- Users can create blog posts with titles, descriptions, and images through the Django Admin Panel.
- Application displays all published blog posts with their images and short descriptions.
- Users can open individual blog posts to view their complete descriptions.
- Existing blog posts can be edited or deleted through the website.
- Django models store blog details, including creation and update timestamps.
- Uploaded images are stored in the media directory and displayed dynamically using Django templates.
- Bootstrap is used to create a responsive layout for displaying blog posts.
1. Create Django Project
Start by creating a Django project named blogsite and an app named gallery.
django-admin startproject blogsite
cd blogsite
python manage.py startapp gallery
Explanation:
- startproject creates a new Django project named blogsite.
- cd blogsite navigates into the project directory.
- startapp creates a Django application named gallery.
Add gallery to the INSTALLED_APPS list in blogsite/settings.py.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'gallery',
]
Explanation:
- INSTALLED_APPS contains all Django applications enabled in the project.
- Adding gallery registers the application with the Django project.
2. Creating Product Model
Product model represents a blog post and stores its title, description, image, and timestamps.
Open gallery/models.py and add the following code:
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
image = models.ImageField(upload_to='products/')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def edit(self, name, description, image):
self.name = name
self.description = description
self.image = image
self.save()
def short_description(self):
# Split the description into words
words = self.description.split()
if len(words) > 50:
# Join the first 50 words and add "..." at the end
return ' '.join(words[:30]) + '...'
else:
# If the description is already less than 50 words, return it as is
return self.description
Explanation:
- name stores the title of the blog post.
- description stores the complete blog content.
- image stores the uploaded image in the products/ directory inside the media folder.
- created_at automatically records when a blog post is created.
- updated_at automatically records when a blog post is modified.
- __str__() returns the blog title as the readable representation of the object.
- short_description() returns the first 50 words of the description for displaying blog previews.
3. Registering Model in Django Admin
Register the Product model in the Django Admin Panel so that administrators can create and manage blog posts.
Open gallery/admin.py and add:
from django.contrib import admin
from .models import Product
admin.site.register(Product)
Explanation:
- admin.site.register(Product) registers the Product model with the Django Admin Panel.
- Administrators can add, view, update, and delete blog posts through the admin interface.
4. Creating Model Form
Create gallery/forms.py to define a Django ModelForm for editing existing blog posts.
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ['name', 'description', 'image']
Explanation:
- ModelForm automatically generates form fields using the Product model.
- Model attribute specifies which model the form is associated with.
- Fields attribute specifies the model fields that can be edited.
- Django handles form validation and saving the updated information.
5. Defining Views
Create views in gallery/views.py to display, edit, and delete blog posts.
from django.shortcuts import render, redirect, get_object_or_404
from .models import Product
from .forms import ProductForm
def product_list(request):
products = Product.objects.all()
return render(request, 'gallery/index.html', {'products': products})
def product_detail(request, pk):
product = get_object_or_404(Product, pk=pk)
return render(request, 'gallery/index2.html', {'product': product})
def edit_product(request, pk):
product = get_object_or_404(Product, pk=pk)
if request.method == 'POST':
form = ProductForm(request.POST, request.FILES, instance=product)
if form.is_valid():
form.save()
return redirect('product_list')
else:
form = ProductForm(instance=product)
return render(request, 'gallery/edit.html', {'form': form})
def delete_product(request, pk):
product = get_object_or_404(Product, pk=pk)
if request.method == 'POST':
product.delete()
return redirect('product_list')
return render(request, 'gallery/delete.html', {'product': product})
Explanation:
- product_list() retrieves all blog posts from the database and displays them on the homepage.
- product_detail() retrieves an individual blog post using its primary key and displays its complete details.
- edit_product() loads the existing post into a form and saves the changes after validation.
- delete_product() deletes the selected blog post when the user submits the confirmation form.
- get_object_or_404() retrieves an object or returns a 404 error if it does not exist.
- redirect() sends the user back to the blog homepage after editing or deleting a post.
- request.FILES handles image uploads when editing a blog post.
6. Configuring URLs
Creating gallery/urls.py to define URL patterns for displaying, editing, and deleting blog posts.
from django.urls import path
from . import views
urlpatterns = [
path('', views.product_list, name='product_list'),
path('<int:pk>/', views.product_detail, name='product_detail'),
path('<int:pk>/edit/', views.edit_product, name='edit_product'),
path('<int:pk>/delete/', views.delete_product, name='delete_product'),
]
Explanation:
- Empty path maps the homepage to product_list().
- <int:pk>/ displays an individual blog post using its primary key.
- <int:pk>/edit/ opens the editing form for the selected post.
- <int:pk>/delete/ opens the deletion confirmation page.
- Name attribute provides a name for each URL pattern that can be referenced in Django templates.
Now open blogsite/urls.py and include the gallery app URLs.
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('gallery.urls')),
]
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT
)
Explanation:
- admin.site.urls enables the Django Admin Panel.
- include('gallery.urls') connects the project's URL configuration with the gallery app.
- static() serves uploaded media files during local development.
- DEBUG condition ensures that this media-serving configuration is used only during development.
6. Configuring Media Settings
Django requires media settings to manage uploaded images.
Open blogsite/settings.py and add:
import os
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Explanation:
- MEDIA_URL defines the URL prefix used to access uploaded media files.
- MEDIA_ROOT specifies the filesystem directory where uploaded images are stored.
- Uploaded blog images are saved inside the media/products/ directory.
7. Creating HTML Templates
Create the following directory structure inside the gallery app:
gallery/
templates/
gallery/
index.html
index2.html
edit.html
delete.html
Each template handles a specific operation of the blogging platform.
1. edit.html : Template displays a form for updating an existing blog post.
<h2>Edit Blog Post</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save Changes</button>
</form>
Explanation:
- POST method submits the updated blog information.
- enctype="multipart/form-data" allows users to upload image files.
- {% csrf_token %} protects the form against CSRF attacks.
- {{ form.as_p }} displays the form fields as HTML paragraphs.
- Submit button sends the updated information to the Django view.
2. delete.html : This template displays a confirmation message before deleting a blog post.
<h2>Delete Blog Post</h2>
<p>Are you sure you want to delete "{{ product.name }}"?</p>
<form method="post">
{% csrf_token %}
<button type="submit">Yes, Delete</button>
</form>
Explanation:
- {{ product.name }} displays the title of the selected blog post.
- {% csrf_token %} protects the deletion form against CSRF attacks.
- POST request confirms the deletion operation.
- After deletion, the user is redirected to the blog homepage.
3. index.html : This template displays all blog posts on the homepage using Bootstrap cards.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Website</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<h1>Today's New Blogs</h1>
<div class="row">
{% for product in products %}
<div class="col-md-4 mb-4">
<div class="card">
<a href="{% url 'product_detail' product.pk %}">
<img src="{{ product.image.url }}"
alt="{{ product.name }}"
class="card-img-top">
</a>
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
<p class="card-text">
{{ product.short_description }}
</p>
<a href="{% url 'edit_product' product.pk %}">Edit</a>
<a href="{% url 'delete_product' product.pk %}">Delete</a>
<br>
<small>Created at: {{ product.created_at }}</small>
<br>
<small>Updated at: {{ product.updated_at }}</small>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
Explanation:
- {% for product in products %} iterates through all blog posts retrieved from the database.
- Bootstrap cards organize each blog post into a separate container.
- {{ product.image.url }} displays the uploaded blog image.
- {{ product.name }} displays the blog title.
- {{ product.short_description }} displays a shortened version of the blog content.
- Edit and Delete links navigate to their respective operations.
- created_at and updated_at display the timestamps of each blog post.
- Bootstrap CSS and JavaScript files provide styling and interface functionality.
4. index2.html : This template displays the complete details of an individual blog post.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ product.name }} - Blog Detail</title>
</head>
<body>
<h1>{{ product.name }} - Blog</h1>
<div>
<img src="{{ product.image.url }}"
alt="{{ product.name }}"
width="200">
</div>
<h2>{{ product.name }}</h2>
<p>{{ product.description }}</p>
<a href="{% url 'edit_product' product.pk %}">Edit</a>
<a href="{% url 'delete_product' product.pk %}">Delete</a>
<br>
<a href="{% url 'product_list' %}">Back to Blogs Home Page</a>
</body>
</html>
Explanation:
- {{ product.name }} displays the title of the selected blog post.
- {{ product.image.url }} displays its uploaded image.
- {{ product.description }} displays the complete blog content.
- Edit and Delete links allow users to modify or remove the selected post.
- Back to Blogs Home Page link redirects users to the homepage.
8. Installing Required Packages
Make sure to install Pillow for image handling:
pip install Pillow
9. Database Setup and Superuser Creation
Apply Migrations
python manage.py makemigrations
python manage.py migrate
Create a superuser to access the Django Admin Panel.
python manage.py createsuperuser
You will be prompted to enter a username, email, and password.
8. Running Project
Start the Django development server using:
python manage.py runserver
Log in using the superuser credentials and add blog entries with images through the Product model.

Output:
.png)


