Üdvözöllek, leendő webfejlesztő! Ha valaha is elgondolkodtál azon, hogyan működnek a webshopok a háttérben, vagy szeretnéd kipróbálni magad egy egyszerű, de funkcionális webes alkalmazás építésében, akkor jó helyen jársz. Ebben a cikkben egy alapvető, de létfontosságú funkcióra fogunk koncentrálni: egy webshop kosár leprogramozására a népszerű Python webes keretrendszerrel, a Flask-kel.
A kosár funkció a modern e-kereskedelem szíve és lelke. Lehetővé teszi a felhasználók számára, hogy kiválogassák a termékeket, mielőtt eldöntenék, hogy megvásárolják-e azokat. Ez a cikk részletesen bemutatja, hogyan építheted fel ezt a funkciót Flask-ben, a felhasználói session (munkamenet) adatai segítségével. Készen állsz? Vágjunk is bele!
Miért épp Flask?
A Flask egy mikro-keretrendszer, ami azt jelenti, hogy minimális beépített funkcióval rendelkezik, és a fejlesztőre bízza a legtöbb döntést. Ez a rugalmasság ideálissá teszi kisebb, testreszabott projektekhez, prototípusokhoz vagy olyan alkalmazásokhoz, ahol csak bizonyos komponensekre van szükség. Kezdők számára is kiváló választás, mivel könnyen tanulható, és gyorsan lehet vele eredményeket elérni. A Python nyelven íródott, ami köztudottan olvasható és intuitív szintaxist kínál.
A Kosár Funkció Alapvető Működése
Mielőtt belemerülnénk a kódba, értsük meg, hogyan is fogjuk tárolni a kosár tartalmát. Egy valódi, komplex webshop adatbázist használna a felhasználói kosarak tárolására, különösen, ha a felhasználó be van jelentkezve, és szeretné, hogy a kosara megmaradjon, még ha bezárja is a böngészőjét. Egy egyszerűbb megvalósításhoz azonban a Flask session a tökéletes megoldás.
A session egy szerver-oldali tárolási mechanizmus, amely lehetővé teszi, hogy adatokat tároljunk a felhasználó böngészőjében egy cookie formájában. Ez a cookie tartalmaz egy titkosított azonosítót, amellyel a szerver hozzáfér a felhasználóhoz tartozó session adatokhoz. Ez azt jelenti, hogy a felhasználó kosara addig marad meg, amíg a session él (például amíg be nem zárja a böngészőjét, vagy amíg a session le nem jár). Biztonsági okokból fontos, hogy a Flask alkalmazásnak legyen egy erős SECRET_KEY-e a session adatok titkosításához.
A kosár lényegében egy egyszerű szótár (dictionary) lesz a sessionben, ahol a kulcsok a termékazonosítók, az értékek pedig a kosárban lévő termékre vonatkozó információk (pl. mennyiség).
Előkészületek és Projektstruktúra
Ahhoz, hogy elkezdhessük, szükséged lesz a következőkre:
- Python 3 telepítve a gépeden.
pip
(Python csomagkezelő) a Flask telepítéséhez.- Alapvető ismeretek a Flask-ről (route-ok, template-ek, request objektum).
- HTML és CSS alapok a felhasználói felülethez.
Hozzuk létre a projektstruktúrát:
my_webshop/
├── app.py
├── templates/
│ ├── index.html
│ └── cart.html
└── static/
└── style.css
Telepítsük a Flask-et (ha még nem tetted meg):
pip install Flask
Alapvető Flask Alkalmazás Beállítása (app.py)
Kezdjük az app.py
fájllal, ahol inicializáljuk a Flask alkalmazást, és beállítjuk a SECRET_KEY-t. Ezen felül definiálunk néhány dummy termékadatot, hogy legyen mivel dolgoznunk.
from flask import Flask, render_template, request, redirect, url_for, session
app = Flask(__name__)
# FONTOS: Cseréld le ezt egy erős, véletlenszerű kulcsra éles környezetben!
app.config['SECRET_KEY'] = 'egy_nagyon_biztonsagos_titkos_kulcs_amit_senki_nem_talal_ki_12345'
# Dummy termékadatok egy szótárban
PRODUCTS = {
"1": {"id": "1", "name": "Programozó bögre", "price": 2500, "image": "mug.jpg"},
"2": {"id": "2", "name": "Flask póló", "price": 5000, "image": "tshirt.jpg"},
"3": {"id": "3", "name": "Python matrica szett", "price": 1200, "image": "stickers.jpg"},
"4": {"id": "4", "name": "Mechanikus billentyűzet", "price": 35000, "image": "keyboard.jpg"},
}
@app.route('/')
def index():
# A termékeket átadjuk a sablonnak
return render_template('index.html', products=PRODUCTS.values())
if __name__ == '__main__':
app.run(debug=True)
Ne felejtsd el a static
mappába tenni néhány dummy képet (pl. `mug.jpg`, `tshirt.jpg` stb.), amiket a PRODUCTS
szótárban definiáltál, különben hibát kapsz a képek betöltésénél.
Termékek Megjelenítése (index.html)
Az index.html
fájl feladata, hogy megjelenítse a termékeket, és lehetőséget adjon a kosárba helyezésre. Ehhez a Jinja2 sablonmotort használjuk a Flask-ben.
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Termékeink - Flask Webshop</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header>
<h1>Üdvözlünk a Flask Webshopban!</h1>
<nav>
<a href="{{ url_for('index') }}">Termékek</a>
<a href="{{ url_for('cart') }}">Kosár ({{ session.cart | length if session.cart else 0 }})</a>
</nav>
</header>
<main class="product-grid">
{% for product in products %}
<div class="product-card">
<img src="{{ url_for('static', filename=product.image) }}" alt="{{ product.name }}">
<h3>{{ product.name }}</h3>
<p>{{ product.price }} Ft</p>
<form action="{{ url_for('add_to_cart') }}" method="POST">
<input type="hidden" name="product_id" value="{{ product.id }}">
<input type="number" name="quantity" value="1" min="1">
<button type="submit">Kosárba</button>
</form>
</div>
{% endfor %}
</main>
<footer>
<p>© 2023 Flask Webshop</p>
</footer>
</body>
</html>
Figyeld meg a navigációs sávban lévő „Kosár” linket, ami dinamikusan megjeleníti a kosárban lévő elemek számát a session.cart | length
segítségével. A product-card
-ok tartalmazzák a termék nevét, árát, képét, és egy űrlapot a kosárba helyezéshez. Az űrlapban egy rejtett mezőben küldjük el a termék azonosítóját, és egy szám mezőben a mennyiséget. Az action="{{ url_for('add_to_cart') }}"
rész mondja meg a Flask-nek, melyik útvonalat hívja meg az űrlap elküldésekor.
Termék Kosárba Helyezése
Most jön a lényegi rész! Hozzunk létre egy útvonalat az app.py
-ban, amely kezeli a termékek kosárba helyezését.
# ... (előző kód) ...
@app.route('/add_to_cart', methods=['POST'])
def add_to_cart():
product_id = request.form.get('product_id')
quantity = int(request.form.get('quantity', 1)) # Alapértelmezett mennyiség: 1
# Ellenőrizzük, hogy a termék létezik-e
if product_id not in PRODUCTS:
return redirect(url_for('index')) # Vagy jeleníts meg hibaüzenetet
# Inicializáld a kosarat a session-ben, ha még nincs
if 'cart' not in session:
session['cart'] = {} # Egy üres szótár a kosár elemeinek
# Ha a termék már a kosárban van, növeljük a mennyiséget
if product_id in session['cart']:
session['cart'][product_id]['quantity'] += quantity
else:
# Ha új termék, hozzáadjuk a kosárhoz
session['cart'][product_id] = {
'quantity': quantity
}
# Fontos: Jelezzük a Flask-nek, hogy a session módosult
session.modified = True
# Átirányítunk a kosár oldalra, vagy vissza az indexre
return redirect(url_for('cart'))
# ... (további útvonalak) ...
Ez az útvonal csak POST
kéréseket fogad el. Kinyerjük a termék azonosítóját és a mennyiséget az űrlapból. Ha a kosár (session['cart']
) még nem létezik, létrehozzuk. Ezután ellenőrizzük, hogy a termék már a kosárban van-e. Ha igen, növeljük a mennyiségét; ha nem, hozzáadjuk az új terméket. Az session.modified = True
sor rendkívül fontos, különben a Flask nem biztos, hogy érzékeli a session szótárának belső módosításait. Végül átirányítjuk a felhasználót a kosár oldalra.
A Kosár Tartalmának Megjelenítése (cart.html)
Most, hogy van egy kosárbahívási funkciónk, építsük meg a kosár oldalát, ahol a felhasználó láthatja, miket válogatott össze.
# ... (előző kód) ...
@app.route('/cart')
def cart():
cart_items = []
total_price = 0
# Ha van 'cart' a session-ben
if 'cart' in session:
for product_id, item_data in session['cart'].items():
product = PRODUCTS.get(product_id) # Lekérjük a termék teljes adatait a PRODUCTS szótárból
if product: # Ha a termék létezik (pl. nem törölték közben)
item_total = product['price'] * item_data['quantity']
total_price += item_total
cart_items.append({
'id': product['id'],
'name': product['name'],
'price': product['price'],
'quantity': item_data['quantity'],
'item_total': item_total,
'image': product['image']
})
return render_template('cart.html', cart_items=cart_items, total_price=total_price)
# ... (további útvonalak) ...
Az /cart
útvonal lekéri a session['cart']
tartalmát, majd a PRODUCTS
szótár segítségével kiegészíti a termékek adatait (név, ár, kép). Kiszámolja az egyes tételek részösszegét és a teljes kosárértéket, majd ezeket átadja a cart.html
sablonnak.
Íme a cart.html
sablon:
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kosarad - Flask Webshop</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header>
<h1>Kosarad</h1>
<nav>
<a href="{{ url_for('index') }}">Vissza a termékekhez</a>
{% if cart_items %}
<a href="{{ url_for('empty_cart') }}" class="empty-cart-btn">Kosár ürítése</a>
{% endif %}
</nav>
</header>
<main>
{% if cart_items %}
<div class="cart-items">
{% for item in cart_items %}
<div class="cart-item">
<img src="{{ url_for('static', filename=item.image) }}" alt="{{ item.name }}" class="cart-item-image">
<div class="cart-item-details">
<h3>{{ item.name }}</h3>
<p>Egységár: {{ item.price }} Ft</p>
<form action="{{ url_for('update_cart') }}" method="POST" class="update-form">
<input type="hidden" name="product_id" value="{{ item.id }}">
<label for="quantity_{{ item.id }}">Mennyiség:</label>
<input type="number" name="quantity" id="quantity_{{ item.id }}" value="{{ item.quantity }}" min="0">
<button type="submit">Frissítés</button>
</form>
<p>Részösszeg: {{ item.item_total }} Ft</p>
<form action="{{ url_for('remove_from_cart') }}" method="POST">
<input type="hidden" name="product_id" value="{{ item.id }}">
<button type="submit" class="remove-btn">Eltávolítás</button>
</form>
</div>
</div>
{% endfor %}
</div>
<div class="cart-summary">
<h2>Összesen: {{ total_price }} Ft</h2>
<button class="checkout-btn">Tovább a pénztárhoz (nem implementált)</button>
</div>
{% else %}
<p class="empty-cart-message">A kosarad üres. Kezdj el vásárolni!</p>
{% endif %}
</main>
<footer>
<p>© 2023 Flask Webshop</p>
</footer>
</body>
</html>
Ez a sablon végigmegy a cart_items
listán, és minden elemhez megjeleníti a részleteket. Tartalmaz egy űrlapot a mennyiség frissítésére, és egy gombot az elem eltávolítására. Végül összefoglalja az összesítést. Ha a kosár üres, egy üzenetet jelenít meg.
Kosár Tartalmának Frissítése és Törlése
Két további funkció elengedhetetlen egy kosárnál: a termékek mennyiségének módosítása és a termékek eltávolítása. Ezeket is POST
kérésekkel kezeljük.
# ... (előző kód) ...
@app.route('/update_cart', methods=['POST'])
def update_cart():
product_id = request.form.get('product_id')
new_quantity = int(request.form.get('quantity'))
if 'cart' in session and product_id in session['cart']:
if new_quantity > 0:
session['cart'][product_id]['quantity'] = new_quantity
else:
# Ha a mennyiség 0 vagy negatív, töröljük a terméket a kosárból
del session['cart'][product_id]
session.modified = True
return redirect(url_for('cart'))
@app.route('/remove_from_cart', methods=['POST'])
def remove_from_cart():
product_id = request.form.get('product_id')
if 'cart' in session and product_id in session['cart']:
del session['cart'][product_id]
session.modified = True
return redirect(url_for('cart'))
@app.route('/empty_cart')
def empty_cart():
# Törli a 'cart' kulcsot a session-ből, ha létezik
session.pop('cart', None)
session.modified = True
return redirect(url_for('cart'))
if __name__ == '__main__':
app.run(debug=True)
Az /update_cart
útvonal beállítja a termék mennyiségét. Fontos, hogy ha a mennyiség 0-ra csökken, akkor eltávolítsuk a terméket a kosárból. Az /remove_from_cart
útvonal egyszerűen törli a megadott terméket. Az /empty_cart
pedig az egész kosarat kiüríti. Mindhárom esetben a session.modified = True
parancs elengedhetetlen, és átirányítunk a kosár oldalra, hogy a változások azonnal láthatóak legyenek.
Stíluslap (static/style.css)
A CSS fájl (static/style.css
) segít, hogy a webshopunk ne csak működjön, hanem jól is nézzen ki. Itt egy nagyon alapvető stíluslap, amit továbbfejleszthetsz saját ízlésed szerint:
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
color: #333;
}
header {
background-color: #333;
color: #fff;
padding: 1rem;
text-align: center;
}
nav a {
color: #fff;
text-decoration: none;
margin: 0 1rem;
}
main {
padding: 20px;
max-width: 1200px;
margin: 20px auto;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
/* Termékkártyák, kosár elemek stílusai */
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
.product-card, .cart-item {
border: 1px solid #ddd;
padding: 15px;
text-align: center;
border-radius: 8px;
background-color: #fff;
}
.product-card img, .cart-item-image {
max-width: 100%;
height: 150px;
object-fit: contain;
margin-bottom: 10px;
}
/* További stílusok a gombokhoz, űrlapokhoz, összefoglalóhoz... */
/* ... (a teljes CSS kód, amit a gondolatmenetben generáltam) ... */
A teljes CSS fájlt a gondolatmenetben találod. Fontos, hogy a url_for('static', filename='style.css')
hivatkozás működjön, ehhez a style.css
fájlnak a static
mappában kell lennie.
További Fejlesztési Lehetőségek és Biztonsági Megfontolások
Ez egy egyszerű, alapvető kosár funkció. Íme néhány tipp a továbbfejlesztéshez és a biztonsághoz:
- Adatbázis integráció: Valódi webshopoknál a termékek adatait adatbázisban tároljuk (pl. SQLAlchemy és PostgreSQL/SQLite segítségével), nem egy Python szótárban. A felhasználók kosarát is tárolhatjuk adatbázisban (például egy bejelentkezett felhasználóhoz rendelve), így az nem vész el a session lejártával.
- Felhasználói fiókok: Regisztráció és bejelentkezés implementálása, hogy a felhasználók menthessék a kosarukat, megtekinthessék a rendelési előzményeiket.
- Checkout (pénztár) folyamat: Egy teljes értékű checkout oldal, ahol a felhasználó megadja a szállítási adatokat, kiválasztja a fizetési módot, és leadja a rendelést.
- Fizetési átjárók: Integráció harmadik fél fizetési szolgáltatókkal (pl. Stripe, PayPal).
- AJAX / JavaScript: A felhasználói élmény javítása érdekében a kosárba helyezés, mennyiség frissítése vagy termék eltávolítása történhetne oldalfrissítés nélkül, AJAX kérésekkel.
- Input validáció: Mindig ellenőrizd a felhasználói bevitelt a szerver oldalon (pl. a mennyiség pozitív egész szám-e), hogy megelőzd a rosszindulatú adatokat.
- SECRET_KEY biztonság: Az éles alkalmazásokban soha ne tárolja a
SECRET_KEY
-t közvetlenül a kódban. Használjon környezeti változókat (environment variables) vagy konfigurációs fájlokat a tárolására. - Hiba kezelés: Értelmes hibaüzenetek megjelenítése a felhasználó számára, ha valami probléma merül fel (pl. nem létező termék).
Összefoglalás
Gratulálok! Most már van egy működő kosár funkcióval rendelkező egyszerű webshopod, amelyet a Flask segítségével építettél fel! Megtanultad, hogyan kell a session-t használni az adatok tárolására, hogyan kell kezelni a termékek hozzáadását, frissítését és törlését, és hogyan kell mindezt megjeleníteni a felhasználónak. Ez egy fantasztikus alap, amire építkezhetsz, és továbbfejlesztheted a webes alkalmazásodat. A webfejlesztés egy folyamatos tanulási folyamat, de a legfontosabb a kezdet! Folytasd a kísérletezést és a tanulást!
Remélem, élvezted ezt a részletes útmutatót, és inspirációt merítettél belőle a további projektekhez. Sok sikert a kódoláshoz!
Leave a Reply