Flask, FastAPI, Django – jak poznawałem trzy Pythony do weba
Większość porównań „Flask vs FastAPI vs Django” wygląda tak samo: tabela cech, kilka benchmarków, konkluzja w stylu „każdy jest świetny, wybierz wedle potrzeb”. Bezużyteczne – bo nie mówi, kiedy który ma sens. Ja poznawałem te trzy frameworki w innej kolejności niż popularność czy data powstania: po kolei, przez robotę, do której akurat byłem mi potrzebny. I właśnie tak chcę je tu pokazać.
Bo każdy z nich w mojej głowie ma jedno zdanie, które go tłumaczy:
- Flask – kiedy chcę najszybciej wystawić HTML.
- FastAPI – kiedy chcę najszybciej wystawić API.
- Django – kiedy chcę użytkowników, panel i bazę z pudełka.
To uproszczenie i za chwilę sam je podważę (bo każdy zrobi i jedno, i drugie). Ale jako mapa startowa działa lepiej niż jakakolwiek tabela.
Flask – najszybciej wystawisz HTML
Od Flaska zaczynałem (mam o tym osobny wpis: Hello World! Instalacja i pierwsze uruchomienie Flask). Powód był prozaiczny: chciałem mieć w przeglądarce coś napisanego w Pythonie, najmniejszym możliwym wysiłkiem. Flask to mikroframework – daje routing, szablony i serwer deweloperski, a całą resztę architektury zostawia tobie.
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return "<h1>Hello z Flaska</h1>"
@app.route("/witaj/<imie>")
def witaj(imie):
# szablon w templates/witaj.html
return render_template("witaj.html", imie=imie)
if __name__ == "__main__":
# uruchomienie wprost: python app.py (alternatywa dla `flask run`)
app.run(debug=True)Uruchomienie to flask run i strona stoi. Nie ma ORM-a, nie ma panelu admina, nie ma systemu użytkowników – i to jest cecha, nie brak. Gdy projekt jest mały albo dopiero sprawdzasz pomysł, nie musisz uczyć się konwencji całego frameworka. Doklejasz tyle, ile potrzebujesz: Flask-SQLAlchemy do bazy, Flask-Login do logowania, Jinja2 (wbudowany) do widoków.
Mój sweet spot dla Flaska: prototyp, mała strona renderowana po stronie serwera, skrypt z webowym frontem, „chcę po prostu zwrócić HTML i nie myśleć o reszcie”.
FastAPI – najszybciej wystawisz API
Po Flasku przyszedł moment, gdy nie chciałem już renderować stron, tylko oddać dane – frontowi w JS albo aplikacji mobilnej. Tu wchodzi FastAPI i jego główny trik: opisujesz dane typami Pythona, a framework robi z tego walidację, serializację i dokumentację.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Zadanie(BaseModel):
tytul: str
zrobione: bool = False
@app.post("/zadania")
async def dodaj(zadanie: Zadanie) -> Zadanie:
# Pydantic sam zwaliduje wejście:
# brak "tytul" albo zły typ => czytelny błąd 422, zero ręcznych ifów
return zadanie
if __name__ == "__main__":
# uruchomienie wprost: python main.py (alternatywa dla `uvicorn main:app`)
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)Dwie rzeczy dostajesz tu za darmo, a w innych frameworkach trzeba je dołożyć:
- Walidacja przez Pydantic. Zły typ albo brak pola = automatyczny, opisowy błąd
422. Nie piszesz ani jednegoif not request.json.get(...). - Interaktywna dokumentacja. FastAPI generuje schemat OpenAPI i serwuje gotowe
/docs(Swagger UI) oraz/redoc. API samo się dokumentuje i samo się testuje z poziomu przeglądarki.
Do tego async jest tu obywatelem pierwszej kategorii (FastAPI stoi na Starlette/ASGI), więc obsługa wielu równoległych żądań I/O – zapytania do bazy, wywołania innych usług – jest naturalna.
Mój sweet spot dla FastAPI: backend dla SPA lub aplikacji mobilnej, mikroserwis, integracja, wszystko gdzie produktem jest JSON, a nie strona.
Django – z pudełka dostajesz to, co tam dłubiesz ręcznie
Przy Django zmienia się perspektywa. Flask i FastAPI dają ci rdzeń i mówią „resztę złóż sam”. Django przychodzi z bateriami: system użytkowników i uprawnień, ORM, migracje, sesje, ochrona CSRF, no i sztandarowy panel administracyjny generowany z modeli.
# models.py
from django.db import models
class Zadanie(models.Model):
tytul = models.CharField(max_length=200)
zrobione = models.BooleanField(default=False)
autor = models.ForeignKey("auth.User", on_delete=models.CASCADE)
# admin.py – trzy linijki i masz pełny CRUD w panelu
from django.contrib import admin
from .models import Zadanie
admin.site.register(Zadanie)Po python manage.py makemigrations && migrate, a następnie python manage.py runserver, wejście na /admin daje gotowy interfejs do zarządzania danymi, z logowaniem, uprawnieniami i filtrowaniem. To, co w Flasku oznaczałoby dobranie kilku rozszerzeń i napisanie widoków, tu jest domyślnym stanem projektu.
Cena tej wygody to konwencje: Django ma swój układ projektu, swój ORM, swój sposób na formularze i widoki. Trzeba je poznać. Ale gdy budujesz pełną aplikację – z kontami użytkowników, panelem dla redakcji czy operacjami CRUD na wielu modelach – ta inwestycja zwraca się od pierwszego dnia.
Mój sweet spot dla Django: kompletna aplikacja z użytkownikami i panelem, projekt, który ma żyć i rosnąć, „nie chcę składać dziesięciu klocków, chcę się zająć logiką”.
Szczera puenta: i tak każdy zrobi jedno i drugie
Teraz obiecane podważenie własnego podziału. Te trzy zdania na górze to domyślna ergonomia, a nie granice możliwości:
- Flask zwróci JSON równie dobrze jak HTML –
return jsonify(...), a zFlask-RESTfulczyBlueprint-ami urośnie do porządnego API. - FastAPI odda HTML – ma wsparcie dla szablonów Jinja2 (
Jinja2Templates) i spokojnie wyrenderuje stronę. - Django zrobi API – przez Django REST Framework (dojrzały, rozbudowany) albo Django Ninja, które wnosi do Django dokładnie ten sam pomysł co FastAPI: endpointy opisane typami i Pydantic, z auto-
/docs.
Różnica nigdy nie brzmi „czy się da”, tylko „ile muszę dołożyć i ile konwencji muszę zaakceptować”. Wystawienie API w czystym Flasku to kilka rozszerzeń i własna struktura. W FastAPI to stan domyślny. Pełny panel admina w FastAPI to spora robota; w Django jest od startu.
Tabela decyzyjna
| Potrzebuję… | Sięgam po | Bo… |
|---|---|---|
| Szybko wystawić stronę / prototyp | Flask | minimum konwencji, doklejasz tylko to, czego użyjesz |
| API z walidacją i dokumentacją | FastAPI | Pydantic + /docs + async w standardzie |
| Pełną aplikację z użytkownikami i panelem | Django | auth, ORM, migracje i admin z pudełka |
| API, ale na bateriach Django | Django + Ninja/DRF | ergonomia FastAPI na fundamencie Django |
To moja mapa, nie wyrok. Kolejność i podział wynikają z tego, jak sam poznawałem te frameworki i do czego ich używam. Twój kontekst – zespół, istniejący kod, wymagania – może przesunąć granice. Aktualny stan i pełną dokumentację sprawdzaj zawsze u źródła: Flask, FastAPI, Django.
Podsumowanie
Gdybym miał zostawić jedno zdanie zamiast całego wpisu: nie wybiera się frameworka „najlepszego”, tylko ten, którego domyślny stan jest najbliżej tego, co masz zbudować. Flask startuje od pustej kartki, FastAPI od gotowego API, Django od gotowej aplikacji. Każdy dojdzie wszędzie – pytanie tylko, ile drogi chcesz przejść sam.
Po stronie front-endu pisałem już o tym, jak platforma webowa dogoniła biblioteki i co dziś można usunąć z projektu. Tu jest analogiczna lekcja dla backendu: zanim dołożysz kolejną zależność albo przepiszesz projekt na „modniejszy” framework, sprawdź, czy ten, który masz, nie robi już tego z pudełka.