Support Online
Skip to main content

Developing a Web Blog Application from Scratch with Flask and SQLite

💡 What You Will Learn in This Guide

In this guide, you will develop a fully functional blog application with Flask, a lightweight and flexible Python web framework. You will integrate your application with the SQLite database, create a modern interface with Bootstrap and prepare dynamic HTML pages thanks to the Jinja template engine. You will also learn CRUD (Create, Read, Update, Delete) operations step by step.


⚙️ Requirements

  • A system with Python 3 and pip installed
  • Virtual environment (venv) information
  • Basic Python knowledge (for loop, functions, variables)
  • Project directory: flask_blog

🔧 Step 1 – Flask Installation and Virtual Environment Setting

Start the virtual environment:

python3 -m venv env
source env/bin/activate

Install Flask:

pip install flask

Test the installation:

python -c "import flask; print(flask.__version__)"

This command verifies that Flask is installed correctly.


🚀 Step 2 – Basic Application (hello.py)

Create file hello.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
return 'Merhaba, Dünya!'

Run the application:

export FLASK_APP=hello
export FLASK_ENV=development
flask run

In the browser, go to http://127.0.0.1:5000 → “Hello, World!” If you see everything is ok.


🧱 Step 3 – Using HTML Templates and Bootstrap

Flask uses the Jinja2 template engine. Now create the templates folder:

mkdir templates

templates/index.html file:

{% extends 'base.html' %}

{% block content %}
<h1>{% block title %} FlaskBlog’a Hoş Geldiniz {% endblock %}</h1>
{% endblock %}

Main template base.html:

<!doctype html>
<html lang="tr">
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-light bg-light">
<a class="navbar-brand" href="{{ url_for('index') }}">FlaskBlog</a>
</nav>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>

This structure provides a common view to all pages with “template inheritance”.


🗃️ Step 4 – SQLite Database Setup

Database Schema (schema.sql)

DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL,
content TEXT NOT NULL
);

Initialize Database (init_db.py)

import sqlite3

connection = sqlite3.connect('database.db')
with open('schema.sql') as f:
connection.executescript(f.read())

cur = connection.cursor()
cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
('İlk Gönderi', 'Bu, ilk blog gönderisidir.'))
connection.commit()
connection.close()

Run:

python init_db.py

If database.db has been created, the database is ready.


📄 Step 5 – List All Posts

Create the file app.py:

import sqlite3
from flask import Flask, render_template

app = Flask(__name__)

def get_db_connection():
conn = sqlite3.connect('database.db')
conn.row_factory = sqlite3.Row
return conn

@app.route('/')
def index():
conn = get_db_connection()
posts = conn.execute('SELECT * FROM posts').fetchall()
conn.close()
return render_template('index.html', posts=posts)

List posts in file index.html:

{% for post in posts %}
<a href="{{ url_for('post', post_id=post['id']) }}">
<h2>{{ post['title'] }}</h2>
</a>
<small>{{ post['created'] }}</small>
<hr>
{% endfor %}

Thanks to the row_factory setting, you can access the columns by name (example: post['title']).


🧠 Step 6 – Viewing a Single Post

Auxiliary function:

from flask import abort

def get_post(post_id):
conn = get_db_connection()
post = conn.execute('SELECT * FROM posts WHERE id = ?', (post_id,)).fetchone()
conn.close()
if post is None:
abort(404)
return post

Route:

@app.route('/<int:post_id>')
def post(post_id):
post = get_post(post_id)
return render_template('post.html', post=post)

post.html:

{% extends 'base.html' %}
{% block content %}
<h2>{{ post['title'] }}</h2>
<p>{{ post['content'] }}</p>
<small>{{ post['created'] }}</small>
{% endblock %}

🧩 Step 7 – Adding a New Post

create.html:

<form method="POST">
<input type="text" name="title" placeholder="Başlık">
<textarea name="content" placeholder="İçerik"></textarea>
<button type="submit">Kaydet</button>
</form>

Route on app.py:

from flask import request, redirect, url_for

@app.route('/create', methods=('GET', 'POST'))
def create():
if request.method == 'POST':
title = request.form['title']
content = request.form['content']
if title:
conn = get_db_connection()
conn.execute('INSERT INTO posts (title, content) VALUES (?, ?)', (title, content))
conn.commit()
conn.close()
return redirect(url_for('index'))
return render_template('create.html')

⚙️ Step 8 – Production Distribution

With Gunicorn:

pip install gunicorn
gunicorn app:app --bind 0.0.0.0:8000

Alternative – on GenixNode:

  1. Upload your Flask project to GitHub
  2. Create “New App” from the App Platform panel
  3. Add the command gunicorn app:app to the run setting
  4. Add environment variables (FLASK_APP, FLASK_ENV)

❓ Frequently Asked Questions (FAQ)

1. Why is Flask a micro framework?

Because it only offers basic features (routing, template); You can optionally add other components.

2. Can I use another DB instead of SQLite?

Yes, it is compatible with systems such as PostgreSQL or MySQL. You just need to replace the link driver.

3. Why isn't the Flask development server used in production?

Due to security and performance shortcomings. Gunicorn or uWSGI is recommended in production.

4. What is the advantage of the url_for() function?

It creates URLs based on route names. Even if the route changes, the links do not break — this is very advantageous for SEO and UX.

5. How can I manage errors?

You can use abort(404) or custom error pages (errorhandler).


🏁 Result

Congratulations 🎉 You have now developed a fully functional web blog application using Flask and SQLite. You learned routing, template inheritance, database operations and CRUD logic.

🚀 More advanced topics: user login, authentication, API integration, image upload.

💡 You can host your project on GenixNode Servers in a few minutes. Easily deploy Python + Flask environment with GenixNode!