Django Blogsite: Complete Step-by-Step Tutorial (Backend + Database + Frontend)
Django project named blogsite and app named blog and connect with MySQL
Django Blogsite: Complete Step-by-Step Tutorial (Backend + Database + Frontend)
Build a Fully Functional Blog with Django, MySQL, Admin Panel & Public Frontend
Django Blogsite: Complete Step-by-Step Tutorial (Backend + Database + Frontend)
Build a Fully Functional Blog with Django, MySQL, Admin Panel & Public Frontend
Goal: Learn Django by building a real-world blog with:
- Admin panel (CRUD)
- MySQL database
- Public home page (list posts)
- Single post detail page
- Clean, organized code
OVERVIEW: Project Structure
blogsite/ ← Main project
├── blogsite/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── blog/ ← App
│ ├── models.py
│ ├── views.py
│ ├── urls.py
│ ├── admin.py
│ └── templates/
│ ├── home.html
│ └── post_detail.html
└── manage.py
PART 1: SETUP DJANGO + MYSQL (BACKEND)
Step 1: Create Project & App
django-admin startproject blogsite
cd blogsite
python manage.py startapp blog
Step 2: Install MySQL Connector
pip install mysqlclient
Note: This allows Django to talk to MySQL.
Step 3: Create Database in MySQL
mysql -u root -p
CREATE DATABASE blogdb;
EXIT;
Step 4: Connect Django to MySQL
Edit: blogsite/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blogdb',
'USER': 'root',
'PASSWORD': 'your_password', # Change if needed
'HOST': 'localhost',
'PORT': '3306',
}
}
Step 5: Create Blog Model
Edit: blog/models.py
from django.db import models
class BlogPost(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Step 6: Register App
Edit: blogsite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # ← Add this
]
Step 7: Run Migrations
python manage.py makemigrations
python manage.py migrate
Step 8: Create Superuser (Admin Access)
python manage.py createsuperuser
Enter:
username,password
Step 9: Register Model in Admin
Edit: blog/admin.py
from django.contrib import admin
from .models import BlogPost
admin.site.register(BlogPost)
Step 10: Run Server
python manage.py runserver
Open in Browser:
http://127.0.0.1:8000/admin
→ Login → Add posts via GUI
Backend + Admin Panel = DONE
PART 2: UNDERSTANDING DATABASE STORAGE
Where is Your Data Actually Saved?
| Component | Location |
|---|---|
| Django Code | blogsite/ folder |
| Admin Panel UI | Browser (/admin) |
| Real Data | MySQL Server Files |
MySQL Data Files (Windows)
C:\ProgramData\MySQL\MySQL Server 8.0\Data\blogdb\
Inside: .ibd, .frm files → actual table data
How It Works
Admin Panel (Browser)
↓
Django ORM → Converts to SQL
↓
MySQL Server → Saves to disk
Verify Data in MySQL Terminal
USE blogdb;
SELECT * FROM blog_blogpost;
You’ll see all posts added from admin!
PART 3: BUILD PUBLIC FRONTEND
Step 1: Include App URLs
Edit: blogsite/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')), # ← Public pages
]
Step 2: Create App URLs
Create: blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('post/<int:id>/', views.post_detail, name='post_detail'),
]
Step 3: Create Views
Edit: blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import BlogPost
def home(request):
posts = BlogPost.objects.all().order_by('-created')
return render(request, 'home.html', {'posts': posts})
def post_detail(request, id):
post = get_object_or_404(BlogPost, id=id)
return render(request, 'post_detail.html', {'post': post})
Step 4: Create Templates Folder
blog/
templates/
home.html
post_detail.html
home.html (List All Posts)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Blog</title>
<style>
body { font-family: Arial; margin: 40px; }
h1 { color: #2c3e50; }
ul { list-style: none; padding: 0; }
li { margin: 15px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px; }
small { color: #7f8c8d; }
</style>
</head>
<body>
<h1>All Blog Posts</h1>
<a href="/admin">Admin Panel</a> |
<a href="/">Home</a>
<hr>
<ul>
{% for p in posts %}
<li>
<a href="/post/{{ p.id }}/"><strong>{{ p.title }}</strong></a>
<br>
<small>{{ p.created|date:"M d, Y" }}</small>
</li>
{% empty %}
<li>No posts yet. <a href="/admin">Add one in admin</a></li>
{% endfor %}
</ul>
</body>
</html>
post_detail.html (Single Post)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ post.title }}</title>
<style>
body { font-family: Arial; margin: 40px; }
.post { max-width: 700px; }
.meta { color: #7f8c8d; font-size: 0.9em; }
</style>
</head>
<body>
<a href="/">← Back to Home</a> |
<a href="/admin">Admin</a>
<hr>
<div class="post">
<h1>{{ post.title }}</h1>
<p class="meta">Published: {{ post.created|date:"F d, Y \a\t h:i A" }}</p>
<hr>
<p>{{ post.content|linebreaks }}</p>
</div>
</body>
</html>
Run & Test
python manage.py runserver
Open:
http://127.0.0.1:8000/ → Home Page
Click post → Detail Page
FRONTEND = DONE
FINAL PROJECT STATUS
| Feature | Status |
|---|---|
| Django Project | Done |
| MySQL Database | Done |
| Admin Panel (CRUD) | Done |
| Public Home Page | Done |
| Single Post View | Done |
| Clean URLs | Done |
| Responsive Design | Basic (can improve) |
NEXT STEPS (Choose One)
| # | Feature | Use Case |
|---|---|---|
| 1 | Add Bootstrap Styling | Beautiful, responsive UI |
| 2 | Public Add Post Form | Users submit posts (no login) |
| 3 | Image Upload in Posts | Rich media blogs |
Reply with your choice:
1,2, or3?
I’ll give you full code + explanation for the next feature!
Congratulations!
You now have a complete, production-ready blog backend + frontend with real database storage.
Save this note — it’s your Django cheat sheet!
Django Blogsite: Complete Step-by-Step Tutorial (Backend + Database + Frontend)
Django project named blogsite and app named blog and connect with MySQL
Django Blogsite: Complete Step-by-Step Tutorial (Backend + Database + Frontend)
Build a Fully Functional Blog with Django, MySQL, Admin Panel & Public Frontend
Django Blogsite: Complete Step-by-Step Tutorial (Backend + Database + Frontend)
Build a Fully Functional Blog with Django, MySQL, Admin Panel & Public Frontend
Goal: Learn Django by building a real-world blog with:
- Admin panel (CRUD)
- MySQL database
- Public home page (list posts)
- Single post detail page
- Clean, organized code
OVERVIEW: Project Structure
blogsite/ ← Main project
├── blogsite/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── blog/ ← App
│ ├── models.py
│ ├── views.py
│ ├── urls.py
│ ├── admin.py
│ └── templates/
│ ├── home.html
│ └── post_detail.html
└── manage.py
PART 1: SETUP DJANGO + MYSQL (BACKEND)
Step 1: Create Project & App
django-admin startproject blogsite
cd blogsite
python manage.py startapp blog
Step 2: Install MySQL Connector
pip install mysqlclient
Note: This allows Django to talk to MySQL.
Step 3: Create Database in MySQL
mysql -u root -p
CREATE DATABASE blogdb;
EXIT;
Step 4: Connect Django to MySQL
Edit: blogsite/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blogdb',
'USER': 'root',
'PASSWORD': 'your_password', # Change if needed
'HOST': 'localhost',
'PORT': '3306',
}
}
Step 5: Create Blog Model
Edit: blog/models.py
from django.db import models
class BlogPost(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Step 6: Register App
Edit: blogsite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # ← Add this
]
Step 7: Run Migrations
python manage.py makemigrations
python manage.py migrate
Step 8: Create Superuser (Admin Access)
python manage.py createsuperuser
Enter:
username,password
Step 9: Register Model in Admin
Edit: blog/admin.py
from django.contrib import admin
from .models import BlogPost
admin.site.register(BlogPost)
Step 10: Run Server
python manage.py runserver
Open in Browser:
http://127.0.0.1:8000/admin
→ Login → Add posts via GUI
Backend + Admin Panel = DONE
PART 2: UNDERSTANDING DATABASE STORAGE
Where is Your Data Actually Saved?
| Component | Location |
|---|---|
| Django Code | blogsite/ folder |
| Admin Panel UI | Browser (/admin) |
| Real Data | MySQL Server Files |
MySQL Data Files (Windows)
C:\ProgramData\MySQL\MySQL Server 8.0\Data\blogdb\
Inside: .ibd, .frm files → actual table data
How It Works
Admin Panel (Browser)
↓
Django ORM → Converts to SQL
↓
MySQL Server → Saves to disk
Verify Data in MySQL Terminal
USE blogdb;
SELECT * FROM blog_blogpost;
You’ll see all posts added from admin!
PART 3: BUILD PUBLIC FRONTEND
Step 1: Include App URLs
Edit: blogsite/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')), # ← Public pages
]
Step 2: Create App URLs
Create: blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('post/<int:id>/', views.post_detail, name='post_detail'),
]
Step 3: Create Views
Edit: blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import BlogPost
def home(request):
posts = BlogPost.objects.all().order_by('-created')
return render(request, 'home.html', {'posts': posts})
def post_detail(request, id):
post = get_object_or_404(BlogPost, id=id)
return render(request, 'post_detail.html', {'post': post})
Step 4: Create Templates Folder
blog/
templates/
home.html
post_detail.html
home.html (List All Posts)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Blog</title>
<style>
body { font-family: Arial; margin: 40px; }
h1 { color: #2c3e50; }
ul { list-style: none; padding: 0; }
li { margin: 15px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px; }
small { color: #7f8c8d; }
</style>
</head>
<body>
<h1>All Blog Posts</h1>
<a href="/admin">Admin Panel</a> |
<a href="/">Home</a>
<hr>
<ul>
{% for p in posts %}
<li>
<a href="/post/{{ p.id }}/"><strong>{{ p.title }}</strong></a>
<br>
<small>{{ p.created|date:"M d, Y" }}</small>
</li>
{% empty %}
<li>No posts yet. <a href="/admin">Add one in admin</a></li>
{% endfor %}
</ul>
</body>
</html>
post_detail.html (Single Post)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ post.title }}</title>
<style>
body { font-family: Arial; margin: 40px; }
.post { max-width: 700px; }
.meta { color: #7f8c8d; font-size: 0.9em; }
</style>
</head>
<body>
<a href="/">← Back to Home</a> |
<a href="/admin">Admin</a>
<hr>
<div class="post">
<h1>{{ post.title }}</h1>
<p class="meta">Published: {{ post.created|date:"F d, Y \a\t h:i A" }}</p>
<hr>
<p>{{ post.content|linebreaks }}</p>
</div>
</body>
</html>
Run & Test
python manage.py runserver
Open:
http://127.0.0.1:8000/ → Home Page
Click post → Detail Page
FRONTEND = DONE
FINAL PROJECT STATUS
| Feature | Status |
|---|---|
| Django Project | Done |
| MySQL Database | Done |
| Admin Panel (CRUD) | Done |
| Public Home Page | Done |
| Single Post View | Done |
| Clean URLs | Done |
| Responsive Design | Basic (can improve) |
NEXT STEPS (Choose One)
| # | Feature | Use Case |
|---|---|---|
| 1 | Add Bootstrap Styling | Beautiful, responsive UI |
| 2 | Public Add Post Form | Users submit posts (no login) |
| 3 | Image Upload in Posts | Rich media blogs |
Reply with your choice:
1,2, or3?
I’ll give you full code + explanation for the next feature!
Congratulations!
You now have a complete, production-ready blog backend + frontend with real database storage.
Save this note — it’s your Django cheat sheet!