DEV Community

Cover image for My project 1 : Building a Mini Blog(with Python + Flask)
Sabin Sim
Sabin Sim

Posted on

My project 1 : Building a Mini Blog(with Python + Flask)

๐Ÿ“ Building a Mini Blog with Flask + SQLite

After learning basic Python syntax and building simple console apps, I wanted to step into real web development using Flask. This project is a minimal blog system where you can write posts, save them into a database, and display them on a clean UI.

Unlike the earlier projects, this one required thinking more about structure โ€” backend logic, routes, HTML templates, and how data flows between each layer. It was definitely more challenging, but I learned a lot through the process. I hope this project helps anyone who wants to start Flask or backend development.


๐Ÿ“‚ 1. Project Structure

flask_blog/
โ”‚โ”€โ”€ app.py                 # Flask server
โ”‚โ”€โ”€ blog.db                # SQLite DB (auto-created)
โ””โ”€โ”€ templates/
    โ”œโ”€โ”€ index.html         # Show all posts
    โ””โ”€โ”€ new.html           # Create new post

๐Ÿง  2. How It Works

  • Flask handles routes: home, new post page, create post
  • SQLite stores blog posts
  • Templates render posts using Jinja2
  • Posts are listed in reverse chronological order

๐Ÿ–ฅ๏ธ 3. Main App (app.py)

from flask import Flask, render_template, request, redirect
import sqlite3

# Initialize the Flask application
app = Flask(__name__)

# ---------- Database Initialization Function ----------
def init_db():
    conn = sqlite3.connect("blog.db")
    cur = conn.cursor()

    cur.execute("""
    CREATE TABLE IF NOT EXISTS posts (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        content TEXT NOT NULL
    )
    """)
    conn.commit()
    conn.close()

# Run DB init on app start
init_db()

# ---------- Home Route ----------
@app.route("/")
def index():
    conn = sqlite3.connect("blog.db")
    cur = conn.cursor()
    cur.execute("SELECT id, title, content FROM posts ORDER BY id DESC")
    posts = cur.fetchall()
    conn.close()

    return render_template("index.html", posts=posts)

# ---------- New Post Page ----------
@app.route("/new")
def new_post():
    return render_template("new.html")

# ---------- Post Creation ----------
@app.route("/create", methods=["POST"])
def create_post():
    title = request.form["title"]
    content = request.form["content"]

    conn = sqlite3.connect("blog.db")
    cur = conn.cursor()
    cur.execute(
        "INSERT INTO posts (title, content) VALUES (?, ?)",
        (title, content)
    )
    conn.commit()
    conn.close()

    return redirect("/")

if __name__ == "__main__":
    app.run(debug=True)
Enter fullscreen mode Exit fullscreen mode

๐Ÿ–ผ๏ธ 4. Templates

๐Ÿ“„ index.html โ€” Display All Posts

<!DOCTYPE html>
<html>
<head>
    <title>Mini Blog</title>
    <style>
        body { font-family: sans-serif; padding: 20px; background-color: #f4f7f9; }
        .post { 
            border: 1px solid #ddd; 
            padding: 15px; 
            margin-bottom: 15px; 
            border-radius: 8px; 
            background-color: white;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
        }
        .post h3 { color: #333; margin-top: 0; }
        .top { 
            display: flex; 
            justify-content: space-between; 
            align-items: center; 
            border-bottom: 2px solid #007bff; 
            margin-bottom: 20px;
            padding-bottom: 10px;
        }
        .top h1 { margin: 0; }
        a { text-decoration: none; color: #007bff; font-weight: bold; }
        a:hover { text-decoration: underline; color: #0056b3; }
    </style>
</head>
<body>

    <div class="top">
        <h1>Mini Blog Posts</h1>
        <a href="/new">Write New Post &rarr;</a>
    </div>

    {% for post in posts %}
    <div class="post">
        <h3>{{ post[1] }}</h3>
        <p>{{ post[2] }}</p>
    </div>
    {% endfor %}

    {% if not posts %}
    <p style="color: #6c757d;">No posts yet. Start writing your first entry!</p>
    {% endif %}

</body>
</html>
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ new.html โ€” Create a New Post

<!DOCTYPE html>
<html>
<head>
    <title>Create New Post</title>
    <style>
        body { font-family: sans-serif; padding: 20px; background-color: #f4f7f9; }
        h1 { color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; margin-bottom: 20px; }
        form { 
            display: flex; 
            flex-direction: column; 
            gap: 15px; 
            width: 90%; 
            max-width: 600px; 
            background-color: white; 
            padding: 20px; 
            border-radius: 8px; 
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        input, textarea { 
            padding: 12px; 
            border: 1px solid #ccc; 
            border-radius: 6px; 
            font-size: 16px; 
        }
        textarea { resize: vertical; }
        button { 
            padding: 12px; 
            background: #28a745; 
            color: #fff; 
            border: none; 
            border-radius: 6px; 
            font-size: 18px;
            cursor: pointer;
            transition: background 0.3s;
        }
        button:hover { background: #1e7e34; }
        .back-link { margin-top: 20px; display: block; color: #6c757d; text-decoration: none; }
    </style>
</head>
<body>

    <h1>Create New Post</h1>

    <form action="/create" method="POST">
        <input type="text" name="title" placeholder="Post Title" required>
        <textarea name="content" rows="10" placeholder="Post Content" required></textarea>
        <button type="submit">Save Post</button>
    </form>

    <a href="/" class="back-link">&larr; Back to Home</a>

</body>
</html>
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“š 5. What I Learned

  • Building a full CRUD workflow (Create + Read)
  • Working with Flask routes, request handling, and redirects
  • Rendering templates using Jinja2
  • Designing clean UI with HTML + CSS
  • Saving data relationally using SQLite

๐Ÿ”ง 6. Try It Yourself โ€” Easy Improvements

If you're new to Flask and want to practice a little more, here are some simple improvements you can try. Each task is beginner-friendly and will help you understand the project more deeply.

  • Add a delete button โ€” let users remove a post they donโ€™t need anymore.
  • Add timestamps โ€” save the date when a post is created and show it under the title.
  • Clear form after submitting โ€” reset the text fields once a post is saved.
  • Improve the design โ€” change colors, spacing, or fonts to make the blog look nicer.
  • Separate the CSS โ€” create a small style.css file instead of keeping the CSS in the HTML.

These are small changes, but each one helps you understand how Flask works step by step. Try one at a time โ€” youโ€™ll be surprised how much you can learn from even tiny improvements!

Top comments (3)

Collapse
 
shahrouzlogs profile image
Shahrouz Nikseresht

Nice work, Sabin! ๐Ÿš€

Building your own mini-blog with Flask is a solid way to practice routing, templates, and overall app structure.

One small suggestion: when working with SQLite, try using a with block for your database connections. It automatically handles opening and closing the connection, which helps avoid issues like unclosed connections or locks later on. It keeps the code cleaner too. โœจ

Looking forward to the next parts! ๐Ÿ”ฅ

Collapse
 
sabin_sim profile image
Sabin Sim

Thanks for the suggestion @shahrouzlogs ! I haven't implemented SQLite yet in this initial phase. I plan to introduce SQLite in the next project or the one after that. Thank you!

Collapse
 
shahrouzlogs profile image
Shahrouz Nikseresht

Totally makes sense. Excited to see the next steps, Sabin ๐Ÿ‘๐Ÿฝ