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, email, 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, or 3?

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!

Last updated: Nov 10, 2025

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, email, 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, or 3?

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!

Last updated: Nov 10, 2025