Hogyan készíts egy egyszerű blogmotort Flask használatával

Üdvözöllek a webfejlesztés izgalmas világában! Gondoltál már arra, hogy saját blogot indítasz, ahol megoszthatod gondolataidat, tapasztalataidat vagy szakértelmedet? Sokan CMS (Tartalomkezelő Rendszer) rendszerekhez fordulnak, mint például a WordPress, de mi lenne, ha elmerülnél a fejlesztésben, és a nulláról építenéd fel a sajátodat? Ebben a cikkben bemutatjuk, hogyan készíthetsz egy egyszerű blogmotort Flask használatával, Python nyelven. A Flask egy könnyed, de rendkívül rugalmas mikrowebkeretrendszer, amely ideális választás kisebb, testreszabott alkalmazásokhoz, így tökéletes arra, hogy megismerkedj a webfejlesztés alapjaival.

Nem kell zseniális programozónak lenned ahhoz, hogy kövess minket. Elég, ha rendelkezel alapvető Python programozási ismeretekkel, és nyitott vagy valami újra. Célunk, hogy egy működőképes blogmotort hozzunk létre, amely képes bejegyzéseket tárolni, megjeleníteni és új bejegyzéseket felvenni. Vágjunk is bele!

Miért éppen Flask?

A webfejlesztési keretrendszerek közül számos közül választhatunk, de a Flask kiváló kiindulópontnak bizonyul a projektünkhöz. Íme néhány ok, amiért érdemes mellette döntenünk:

  • Könnyed és minimalista: A Flask „mikro” keretrendszerként minimálisra csökkenti az alapvető funkciókat, így te döntheted el, milyen komponenseket szeretnél hozzáadni. Ez óriási szabadságot biztosít.
  • Rugalmas: Bár alapfunkciókat nyújt, könnyen bővíthető kiegészítőkkel és saját modulokkal.
  • Egyszerűen tanulható: Tiszta és intuitív API-ja miatt hamar elsajátítható, különösen, ha már ismered a Pythont.
  • Nagy közösség: Számos forrás, dokumentáció és segítőkész közösség áll rendelkezésre, ha elakadnál.

A végeredmény egy olyan Flask alapú blog lesz, amelynek minden egyes részét te magad érted és irányítod.

Előkészületek: Amire szükséged lesz

Mielőtt belevágunk a kódolásba, győződj meg róla, hogy a következő eszközök telepítve vannak a gépeden:

  • Python 3: Ha még nincs, látogass el a python.org oldalra és telepítsd.
  • pip: A Python csomagkezelője, általában a Pythonnal együtt települ.
  • Egy szövegszerkesztő vagy IDE (pl. VS Code, PyCharm).

Virtuális környezet létrehozása

Mielőtt bármilyen Python csomagot telepítenél, erősen ajánlott egy virtuális környezet (venv) létrehozása. Ez segít elszigetelni a projekt függőségeit a globális Python telepítéstől.


# Hozz létre egy új mappát a projektednek
mkdir simple_blog
cd simple_blog

# Hozz létre egy virtuális környezetet
python3 -m venv venv

# Aktiváld a virtuális környezetet (Linux/macOS)
source venv/bin/activate

# Aktiváld a virtuális környezetet (Windows)
venvScriptsactivate

Miután aktiváltad, a parancssorod elején látszani fog a (venv) előtag, jelezve, hogy a virtuális környezetben vagy.

Flask telepítése

Most, hogy a virtuális környezet aktív, telepítsd a Flask-et és a szükséges adatbázis kiegészítőt:


pip install Flask Flask-SQLAlchemy

A Flask-SQLAlchemy egy praktikus Flask kiegészítő, amely megkönnyíti az adatbázisokkal való munkát az SQLAlchemy ORM (Object-Relational Mapper) használatával.

A Projekt struktúrája

Tartsuk rendezetten a dolgokat. Hozz létre a simple_blog mappán belül a következő struktúrát:


simple_blog/
├── venv/                 # Virtuális környezet
├── app.py                # A Flask alkalmazás fő fájlja
├── templates/            # HTML sablonok
│   ├── base.html
│   ├── index.html
│   ├── post.html
│   └── create_post.html
└── static/               # Statikus fájlok (CSS, JS, képek)
    └── style.css

A Flask alkalmazás inicializálása és az adatbázis beállítása

Nyisd meg az app.py fájlt, és kezdjük el a kódolást. Először importáljuk a szükséges modulokat, inicializáljuk a Flask alkalmazást, és konfiguráljuk az adatbázist.


from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

# Flask alkalmazás inicializálása
app = Flask(__name__)

# Adatbázis konfiguráció
# Használunk egy egyszerű SQLite adatbázist, ami egy fájlban tárolja az adatokat
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Elnyomja a figyelmeztetést

# SQLAlchemy inicializálása
db = SQLAlchemy(app)

# Adatbázis modell definíciója
class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    def __repr__(self):
        return f'<Post {self.title}>'

# Adatbázis létrehozása (csak egyszer futtasd, vagy minden alkalommal, amikor törlöd a db fájlt)
with app.app_context():
    db.create_all()

Nézzük meg, mi történik itt:

  • Importáljuk a Flask, render_template, request, redirect, url_for modulokat.
  • Az app = Flask(__name__) sor inicializálja az alkalmazást.
  • Az app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db' beállítja az SQLite adatbázist, amely egy blog.db nevű fájlban fog létrejönni a projekt gyökérkönyvtárában.
  • A db = SQLAlchemy(app) inicializálja az ORM-et.
  • A Post osztály az adatbázisunk tábláját reprezentálja. Minden osztályváltozó egy oszlopot jelent az adatbázisban (id, title, content, created_at). A primary_key=True azt jelenti, hogy az id lesz az elsődleges kulcs.
  • Végül a db.create_all() parancs létrehozza a Post táblát az adatbázisban, ha még nem létezik. Ezt a blokkot csak egyszer kell futtatni, vagy amikor frissíted a modellt, vagy törlöd a blog.db fájlt.

Blogbejegyzések megjelenítése: A főoldal

Most hozzuk létre a főoldalt, ahol az összes blogbejegyzés listázva lesz. Ezt egy „route” (útvonal) segítségével tesszük meg.


# ... (a fenti kód folytatása) ...

@app.route('/')
def index():
    # Lekérdezi az összes bejegyzést a legújabbak elöl
    posts = Post.query.order_by(Post.created_at.desc()).all()
    return render_template('index.html', posts=posts)

# ... (a többi kód ide jön) ...

if __name__ == '__main__':
    app.run(debug=True)

Az @app.route('/') jelzi, hogy ez a függvény fut le, ha a felhasználó a gyökér URL-t (pl. http://127.0.0.1:5000/) látogatja meg. A Post.query.order_by(Post.created_at.desc()).all() lekérdezi az összes bejegyzést az adatbázisból, a létrehozás dátuma szerint csökkenő sorrendben. A render_template('index.html', posts=posts) betölti az index.html sablont, és átadja neki a posts változót.

Blogbejegyzések létrehozása: Az admin felület

Ahhoz, hogy bejegyzéseket tehessünk közzé, szükségünk van egy felületre a létrehozásukhoz. Ez egy egyszerű HTML űrlap lesz.


# ... (a fenti kód folytatása) ...

@app.route('/create', methods=['GET', 'POST'])
def create_post():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        new_post = Post(title=title, content=content)

        try:
            db.session.add(new_post)
            db.session.commit()
            return redirect(url_for('index'))
        except:
            return 'Hiba történt a bejegyzés létrehozásakor.'
    else:
        return render_template('create_post.html')

# ... (a többi kód ide jön) ...

Ez az útvonal két dolgot kezel:

  • GET kérés: Ha valaki csak meglátogatja az /create oldalt, megjelenítjük neki a create_post.html űrlapot.
  • POST kérés: Amikor az űrlapot beküldik, a request.form segítségével kinyerjük a címet és a tartalmat. Létrehozunk egy új Post objektumot, hozzáadjuk az adatbázis munkamenetéhez (db.session.add), majd elmentjük a változásokat (db.session.commit). Végül átirányítjuk a felhasználót a főoldalra (redirect(url_for('index'))).

Egyedi blogbejegyzés megjelenítése

Miután létrehoztuk a bejegyzéseket, szükségünk van egy oldalra, ahol az egyes bejegyzéseket külön-külön is meg tudjuk nézni.


# ... (a fenti kód folytatása) ...

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

# ... (a többi kód ide jön) ...

Az <int:post_id> jelzi, hogy az URL egy egész számot vár paraméterként, amelyet a post_id változó fog megkapni. A Post.query.get_or_404(post_id) megpróbálja lekérdezni a bejegyzést az azonosítója alapján; ha nem találja, automatikusan egy 404-es hibát dob. Ezt követően a post.html sablonba rendereljük az adott bejegyzést.

Sablonok kezelése Jinja2-vel

A Flask a Jinja2 sablonrendszert használja, amely lehetővé teszi, hogy dinamikus HTML oldalakat hozzunk létre Python kódunk alapján. Hozzuk létre a szükséges HTML fájlokat a templates/ mappában.

templates/base.html

Ez lesz az alap sablonunk, amelyet az összes többi oldal örököl. Tartalmazza a weboldal alapvető struktúráját, a CSS fájl linkjét és a navigációs sávot.


<!DOCTYPE html>
<html lang="hu">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}{% endblock %} - Egyszerű Flask Blog</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <nav>
        <a href="{{ url_for('index') }}">Főoldal</a>
        <a href="{{ url_for('create_post') }}">Új Bejegyzés</a>
    </nav>
    <div class="container">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

A {% block title %} és {% block content %} helykitöltők, amelyeket az öröklő sablonok felülírhatnak. A {{ url_for('static', filename='style.css') }} automatikusan generálja a CSS fájl elérési útját.

templates/index.html

Ez fogja listázni az összes blogbejegyzést.


{% extends 'base.html' %}

{% block title %}Blogbejegyzések{% endblock %}

{% block content %}
    <h1>Legújabb Bejegyzések</h1>
    {% if posts %}
        {% for post in posts %}
            <article class="post-preview">
                <h2><a href="{{ url_for('show_post', post_id=post.id) }}">{{ post.title }}</a></h2>
                <p class="post-meta">Közzétéve: {{ post.created_at.strftime('%Y-%m-%d %H:%M') }}</p>
                <p>{{ post.content[:200] }}... <a href="{{ url_for('show_post', post_id=post.id) }}">Olvass tovább</a></p>
            </article>
        {% endfor %}
    {% else %}
        <p>Még nincsenek bejegyzések.</p>
    {% endif %}
{% endblock %}

A {% extends 'base.html' %} jelzi, hogy ez a sablon a base.html-ből örököl. A {% for post in posts %} ciklussal iterálunk a Python kódból átadott posts listán.

templates/post.html

Ez egy egyedi blogbejegyzést jelenít meg.


{% extends 'base.html' %}

{% block title %}{{ post.title }}{% endblock %}

{% block content %}
    <article class="full-post">
        <h1>{{ post.title }}</h1>
        <p class="post-meta">Közzétéve: {{ post.created_at.strftime('%Y-%m-%d %H:%M') }}</p>
        <div class="post-content">
            {{ post.content | safe }}
        </div>
    </article>
    <a href="{{ url_for('index') }}">&lt;</a>
{% endblock %}

A {{ post.content | safe }} azt jelenti, hogy a tartalmat biztonságosan jelenítjük meg, ami azt feltételezi, hogy a tartalom HTML-t tartalmazhat, és nem szeretnénk, ha a Jinja2 automatikusan elmenekítené (escape-elné) a HTML tag-eket. Ez kockázatot jelenthet XSS támadások szempontjából, ha a bejegyzés tartalmát nem szűrjük, de egy egyszerű bloghoz megteszi.

templates/create_post.html

Az űrlap, amellyel új bejegyzéseket hozhatunk létre.


{% extends 'base.html' %}

{% block title %}Új bejegyzés{% endblock %}

{% block content %}
    <h1>Új Blogbejegyzés Létrehozása</h1>
    <form method="POST">
        <label for="title">Cím:</label><br>
        <input type="text" id="title" name="title" required><br><br>

        <label for="content">Tartalom:</label><br>
        <textarea id="content" name="content" rows="10" required></textarea><br><br>

        <input type="submit" value="Bejegyzés Létrehozása">
    </form>
{% endblock %}

Statikus fájlok és stílus

A static/ mappában tárolt fájlok (pl. CSS, JavaScript, képek) az url_for('static', filename='...') segítségével érhetők el. Hozz létre egy static/style.css fájlt, és adj hozzá néhány alapvető stílust, hogy a blogod ne nézzen ki túl puritánul.


/* static/style.css */
body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    margin: 0;
    padding: 0;
    background: #f4f4f4;
    color: #333;
}
.container {
    width: 80%;
    margin: auto;
    overflow: hidden;
    padding: 20px 0;
}
nav {
    background: #333;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}
nav a {
    color: #fff;
    text-decoration: none;
    padding: 0 15px;
}
nav a:hover {
    color: #ffd700;
}
.post-preview, .full-post {
    background: #fff;
    padding: 20px;
    margin-bottom: 20px;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.post-preview h2 a, .full-post h1 {
    color: #333;
    text-decoration: none;
}
.post-meta {
    font-size: 0.9em;
    color: #777;
    margin-bottom: 10px;
}
form input[type="text"],
form textarea {
    width: 100%;
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    box-sizing: border-box; /* Padding is included in width */
}
form input[type="submit"] {
    background: #333;
    color: #fff;
    padding: 10px 15px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
form input[type="submit"]:hover {
    background: #555;
}

A blogmotor futtatása

Most, hogy minden a helyén van, futtathatjuk a Flask alkalmazásunkat. Győződj meg róla, hogy a virtuális környezet aktív, és a projekt gyökérkönyvtárában vagy (ahol az app.py található), majd futtasd a következő parancsot:


python app.py

Vagy beállíthatod a Flask CLI-t is:


export FLASK_APP=app.py # Linux/macOS
set FLASK_APP=app.py   # Windows

flask run

Látnod kell egy üzenetet, ami valahogy így néz ki:


* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Nyisd meg a böngésződet, és navigálj a megadott címre (általában http://127.0.0.1:5000/). Gratulálunk! Látnod kell az egyszerű Flask blogod főoldalát. Kattints az „Új Bejegyzés” linkre, írj egy címet és tartalmat, majd mentsd el. Látni fogod, hogy az új bejegyzés megjelenik a főoldalon.

További fejlesztési lehetőségek

Ez a blogmotor egy alapvető, de működőképes kiindulópont. Íme néhány ötlet, hogyan fejlesztheted tovább:

  • Bejegyzések szerkesztése és törlése: Készíts útvonalakat és sablonokat a meglévő bejegyzések módosítására vagy eltávolítására.
  • Felhasználói azonosítás: Implementálj egy bejelentkezési rendszert (pl. Flask-Login segítségével), hogy csak hitelesített felhasználók hozhassanak létre vagy szerkeszthessenek bejegyzéseket.
  • Markdown támogatás: Használj egy Markdown parser könyvtárat (pl. Mistune vagy Markdown), hogy a bejegyzések tartalmát Markdown formátumban lehessen írni és megjeleníteni.
  • Kategóriák és címkék: Bővítsd az adatbázis modellt kategóriákkal és címkékkel, hogy rendszerezni tudd a bejegyzéseket.
  • Keresés és lapozás: Add hozzá a keresési funkciót és a lapozást, ha sok bejegyzésed lesz.
  • Kommentek: Integrálj egy egyszerű kommentrendszert, vagy használj egy harmadik féltől származó szolgáltatást (pl. Disqus).
  • Fejlettebb adatbázis: Ha nagyobb projektre készülsz, érdemes lehet más adatbázisokat (pl. PostgreSQL, MySQL) is kipróbálni a Flask-SQLAlchemy segítségével.

Összefoglalás

Gratulálunk! Elkészítetted az első Flask blogmotorodat. Végigjártuk a projekt beállítását, az adatbázis modell létrehozását az SQLAlchemy ORM használatával, az útvonalak definiálását, az űrlapok kezelését, és a tartalom megjelenítését a Jinja2 sablonrendszerrel. Láthatod, hogy a Flask mennyire erőteljes és rugalmas eszköz, amellyel viszonylag kevés kóddal is működőképes webalkalmazásokat hozhatunk létre.

Ez a projekt kiváló alapot nyújt a webfejlesztés Pythonnal való mélyebb megismeréséhez. Ne félj kísérletezni, módosítani a kódot, és új funkciókat hozzáadni. A tanulás legjobb módja, ha gyakoroljuk és felfedezzük a lehetőségeket. Sok sikert a további fejlesztésekhez és a blogoláshoz!

Leave a Reply

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük