Das Routing-System von Flask bildet das Herzstück der URL-Verarbeitung und bestimmt, welche Funktionen bei bestimmten URL-Aufrufen ausgeführt werden. Flask verwendet Dekoratoren zur Definition von Routes, die eine direkte Zuordnung zwischen URLs und Python-Funktionen ermöglichen.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Startseite der Anwendung'
@app.route('/ueber-uns')
def about():
return 'Informationen über unser Unternehmen'
@app.route('/kontakt')
def contact():
return 'Kontaktinformationen'Flask unterstützt dynamische URL-Segmente durch Variable Rules. Diese ermöglichen die Übergabe von Parametern direkt über die URL-Struktur.
@app.route('/benutzer/<username>')
def show_user_profile(username):
return f'Benutzerprofil: {username}'
@app.route('/artikel/<int:artikel_id>')
def show_article(artikel_id):
return f'Artikel Nummer: {artikel_id}'
@app.route('/kategorie/<string:kategorie_name>')
def show_category(kategorie_name):
return f'Kategorie: {kategorie_name}'
@app.route('/preis/<float:betrag>')
def show_price(betrag):
return f'Preis: {betrag:.2f} EUR'string: (Standard) Akzeptiert Text ohne Schrägstriche int: Positive Ganzzahlen float: Positive Fließkommazahlen path: Wie string, aber akzeptiert auch Schrägstriche uuid: UUID-Strings
from werkzeug.routing import BaseConverter
class ListConverter(BaseConverter):
def to_python(self, value):
return value.split(',')
def to_url(self, values):
return ','.join(BaseConverter.to_url(value) for value in values)
app.url_map.converters['list'] = ListConverter
@app.route('/tags/<list:tag_liste>')
def show_tags(tag_liste):
return f'Tags: {", ".join(tag_liste)}'@app.route('/api/v1/users')
def api_users():
return 'API: Benutzerliste'
@app.route('/admin/dashboard')
def admin_dashboard():
return 'Administrator Dashboard'
# Subdomain-Routing
@app.route('/', subdomain='api')
def api_index():
return 'API Startseite'@app.route('/artikel/<int:id>', methods=['GET'])
def get_article(id):
return f'Artikel {id} anzeigen'
@app.route('/suche', methods=['GET', 'POST'], strict_slashes=False)
def search():
return 'Suchfunktion'
@app.route('/legacy-url', redirect_to='/neue-url')
def legacy_redirect():
pass # Wird automatisch weitergeleitetHTTP-Methoden definieren die Art der Anfrage und bestimmen, welche Aktionen auf Serverseite ausgeführt werden sollen. Flask unterstützt alle Standard-HTTP-Methoden für RESTful-Anwendungen.
GET-Requests dienen dem Abrufen von Daten ohne Seiteneffekte auf dem Server.
from flask import request, jsonify
@app.route('/artikel', methods=['GET'])
def get_articles():
# Artikel aus Datenbank abrufen
return jsonify({
'artikel': [
{'id': 1, 'titel': 'Erste Nachricht'},
{'id': 2, 'titel': 'Zweite Nachricht'}
]
})
@app.route('/artikel/<int:id>', methods=['GET'])
def get_article(id):
# Einzelnen Artikel abrufen
return jsonify({'id': id, 'titel': f'Artikel {id}'})POST-Requests erstellen neue Ressourcen oder führen Aktionen mit Seiteneffekten aus.
from flask import request, jsonify
@app.route('/artikel', methods=['POST'])
def create_article():
data = request.get_json()
if not data or 'titel' not in data:
return jsonify({'fehler': 'Titel ist erforderlich'}), 400
# Artikel in Datenbank speichern
new_article = {
'id': 123,
'titel': data['titel'],
'inhalt': data.get('inhalt', '')
}
return jsonify(new_article), 201
@app.route('/benutzer/login', methods=['POST'])
def login():
username = request.form.get('username')
password = request.form.get('password')
if not username or not password:
return jsonify({'fehler': 'Benutzername und Passwort erforderlich'}), 400
# Authentifizierung prüfen
return jsonify({'nachricht': 'Anmeldung erfolgreich'})PUT-Requests aktualisieren bestehende Ressourcen vollständig.
@app.route('/artikel/<int:id>', methods=['PUT'])
def update_article(id):
data = request.get_json()
if not data:
return jsonify({'fehler': 'JSON-Daten erforderlich'}), 400
# Artikel vollständig aktualisieren
updated_article = {
'id': id,
'titel': data.get('titel', ''),
'inhalt': data.get('inhalt', ''),
'autor': data.get('autor', '')
}
return jsonify(updated_article)PATCH-Requests für partielle Updates.
@app.route('/artikel/<int:id>', methods=['PATCH'])
def patch_article(id):
data = request.get_json()
# Nur übermittelte Felder aktualisieren
updated_fields = {}
if 'titel' in data:
updated_fields['titel'] = data['titel']
if 'inhalt' in data:
updated_fields['inhalt'] = data['inhalt']
return jsonify({'id': id, 'aktualisiert': updated_fields})DELETE-Requests entfernen Ressourcen.
@app.route('/artikel/<int:id>', methods=['DELETE'])
def delete_article(id):
# Artikel aus Datenbank löschen
return '', 204 # No Content
@app.route('/benutzer/<int:user_id>/artikel', methods=['DELETE'])
def delete_user_articles(user_id):
# Alle Artikel eines Benutzers löschen
deleted_count = 5 # Beispielwert
return jsonify({'geloescht': deleted_count})@app.route('/artikel/<int:id>', methods=['GET', 'PUT', 'DELETE'])
def handle_article(id):
if request.method == 'GET':
return jsonify({'id': id, 'titel': f'Artikel {id}'})
elif request.method == 'PUT':
data = request.get_json()
return jsonify({'id': id, 'aktualisiert': True})
elif request.method == 'DELETE':
return '', 204
# Alternative: Separate Funktionen für bessere Lesbarkeit
@app.route('/benutzer/<int:id>')
def get_user(id):
return jsonify({'id': id, 'name': f'Benutzer {id}'})
@app.route('/benutzer/<int:id>', methods=['PUT'])
def update_user(id):
return jsonify({'id': id, 'aktualisiert': True})
@app.route('/benutzer/<int:id>', methods=['DELETE'])
def delete_user(id):
return '', 204URL-Parameter und Query-Parameter bieten verschiedene Möglichkeiten zur Datenübertragung an den Server. URL-Parameter sind Teil der Route-Definition, während Query-Parameter optional über das request-Objekt zugänglich sind.
@app.route('/produkt/<kategorie>/<int:produkt_id>')
def show_product(kategorie, produkt_id):
return f'Kategorie: {kategorie}, Produkt-ID: {produkt_id}'
@app.route('/archiv/<int:jahr>/<int:monat>')
def show_archive(jahr, monat):
if monat < 1 or monat > 12:
return 'Ungültiger Monat', 400
return f'Archiv für {monat:02d}/{jahr}'
@app.route('/datei/<path:dateiname>')
def serve_file(dateiname):
# Dateiname kann Verzeichnisse enthalten
return f'Datei: {dateiname}'from flask import request
@app.route('/suche')
def search():
query = request.args.get('q', '')
seite = request.args.get('seite', 1, type=int)
pro_seite = request.args.get('pro_seite', 10, type=int)
sortierung = request.args.get('sort', 'datum')
if not query:
return 'Suchbegriff fehlt', 400
results = {
'suchbegriff': query,
'seite': seite,
'pro_seite': pro_seite,
'sortierung': sortierung,
'ergebnisse': []
}
return jsonify(results)
@app.route('/filter')
def filter_items():
# Mehrere Werte für einen Parameter
kategorien = request.args.getlist('kategorie')
min_preis = request.args.get('min_preis', type=float)
max_preis = request.args.get('max_preis', type=float)
verfuegbar = request.args.get('verfuegbar', type=bool)
filter_params = {
'kategorien': kategorien,
'preis_von': min_preis,
'preis_bis': max_preis,
'nur_verfuegbare': verfuegbar
}
return jsonify(filter_params)@app.route('/api/artikel')
def api_articles():
try:
seite = request.args.get('seite', 1, type=int)
if seite < 1:
raise ValueError('Seite muss größer als 0 sein')
limit = request.args.get('limit', 10, type=int)
if limit < 1 or limit > 100:
raise ValueError('Limit muss zwischen 1 und 100 liegen')
sort_by = request.args.get('sort_by', 'created_at')
allowed_sorts = ['created_at', 'title', 'author']
if sort_by not in allowed_sorts:
raise ValueError(f'Ungültige Sortierung. Erlaubt: {", ".join(allowed_sorts)}')
direction = request.args.get('direction', 'desc').lower()
if direction not in ['asc', 'desc']:
raise ValueError('Richtung muss "asc" oder "desc" sein')
except ValueError as e:
return jsonify({'fehler': str(e)}), 400
return jsonify({
'seite': seite,
'limit': limit,
'sortierung': f'{sort_by} {direction}'
})@app.route('/benutzer/<int:user_id>/artikel')
def user_articles(user_id):
# URL-Parameter
if user_id <= 0:
return 'Ungültige Benutzer-ID', 400
# Query-Parameter
status = request.args.get('status', 'alle')
jahr = request.args.get('jahr', type=int)
filter_info = {
'benutzer_id': user_id,
'status_filter': status
}
if jahr:
filter_info['jahr_filter'] = jahr
return jsonify(filter_info)Die url_for-Funktion generiert URLs basierend auf Endpunkt-Namen und bietet Flexibilität bei URL-Änderungen. Sie ist essentiell für die Wartbarkeit von Flask-Anwendungen.
from flask import url_for, redirect, render_template
@app.route('/')
def index():
return render_template('index.html')
@app.route('/benutzer/<int:id>')
def user_profile(id):
return f'Benutzerprofil {id}'
@app.route('/artikel/<int:article_id>')
def show_article(article_id):
# URL zu anderem Endpunkt generieren
user_url = url_for('user_profile', id=123)
return f'Artikel {article_id}. <a href="{user_url}">Zum Autor</a>'
@app.route('/weiterleitung')
def redirect_example():
return redirect(url_for('index'))@app.route('/produkt/<kategorie>/<int:id>')
def product_detail(kategorie, id):
return f'Produkt {id} in Kategorie {kategorie}'
@app.route('/navigation')
def navigation():
urls = {
'startseite': url_for('index'),
'produkt_1': url_for('product_detail', kategorie='elektronik', id=1),
'produkt_2': url_for('product_detail', kategorie='buecher', id=42),
'benutzer': url_for('user_profile', id=123)
}
return jsonify(urls)@app.route('/suche')
def search():
return 'Suchergebnisse'
@app.route('/suchlinks')
def search_links():
# Query-Parameter als zusätzliche Argumente
search_electronics = url_for('search', q='laptop', kategorie='elektronik')
search_books = url_for('search', q='python', kategorie='buecher', seite=2)
return f'''
<a href="{search_electronics}">Laptop suchen</a><br>
<a href="{search_books}">Python Bücher (Seite 2)</a>
'''<!-- templates/navigation.html -->
<nav>
<ul>
<li><a href="{{ url_for('index') }}">Startseite</a></li>
<li><a href="{{ url_for('user_profile', id=current_user.id) }}">Mein Profil</a></li>
<li><a href="{{ url_for('search', q='', kategorie='alle') }}">Suche</a></li>
</ul>
</nav>
<!-- Dynamische URLs mit Variablen -->
{% for artikel in artikel_liste %}
<div>
<h3><a href="{{ url_for('show_article', article_id=artikel.id) }}">{{ artikel.titel }}</a></h3>
<p>Von <a href="{{ url_for('user_profile', id=artikel.autor_id) }}">{{ artikel.autor_name }}</a></p>
</div>
{% endfor %}@app.route('/assets')
def asset_links():
css_url = url_for('static', filename='css/style.css')
js_url = url_for('static', filename='js/app.js')
img_url = url_for('static', filename='images/logo.png')
return f'''
<link rel="stylesheet" href="{css_url}">
<script src="{js_url}"></script>
<img src="{img_url}" alt="Logo">
'''from flask import Blueprint
api_bp = Blueprint('api', __name__, url_prefix='/api')
@api_bp.route('/benutzer/<int:id>')
def get_user(id):
return jsonify({'id': id})
@app.route('/api-links')
def api_links():
# Blueprint-Endpunkt mit Präfix
user_api_url = url_for('api.get_user', id=123)
return f'<a href="{user_api_url}">Benutzer API</a>'@app.route('/absolute-urls')
def absolute_urls():
# Absolute URL generieren
abs_url = url_for('index', _external=True)
# URL mit spezifischer Scheme
https_url = url_for('user_profile', id=123, _external=True, _scheme='https')
return f'''
Absolute URL: {abs_url}<br>
HTTPS URL: {https_url}
'''@app.route('/umgebungs-urls')
def environment_urls():
# URLs für verschiedene Umgebungen
if app.config.get('ENV') == 'production':
base_url = 'https://produktion.firma.de'
else:
base_url = 'http://localhost:5000'
# Manuelle URL-Konstruktion wenn nötig
manual_url = f"{base_url}{url_for('user_profile', id=123)}"
return f'Manuelle URL: {manual_url}'from werkzeug.routing import BuildError
@app.route('/sichere-url-generierung')
def safe_url_generation():
try:
# Versuch URL zu generieren
url = url_for('nicht_existierender_endpunkt')
except BuildError:
# Fallback-URL
url = url_for('index')
return redirect(url)Das Routing-System bildet die Grundlage für alle weiteren Flask-Funktionalitäten und ermöglicht die strukturierte Entwicklung von Web-APIs und Anwendungen.