Flask – 03 Jinja Schleifen und Listen
Voraussetzungen
Bevor du mit diesem Modul startest, solltest du bereits vertraut sein mit:
- Python – 04 Listen - Grundlagen von Listen in Python
- Python – 05 For-Schleifen - Schleifen in Python
- Flask – 02 Jinja Templating Grundlagen - Variablen und Bedingungen in Jinja
Warum Schleifen in Templates?
In den meisten Webanwendungen zeigst du Listen von Daten an:
- Eine Liste von Produkten in einem Shop
- Eine To-Do-Liste
- Blog-Beiträge
- Suchergebnisse
- Benutzerprofile
Statt für jeden Eintrag den gleichen HTML-Code zu wiederholen, nutzt du For-Schleifen in Jinja, um Listen dynamisch zu durchlaufen und anzuzeigen.
Das Prinzip
- In Python erstellst du eine Liste mit Daten
- Du übergibst die Liste ans Template
- Im Template durchläufst du die Liste mit einer
{% for %}Schleife - Jinja generiert automatisch HTML für jeden Eintrag
For-Schleifen in Jinja - Die Grundlagen
Einfache Liste durchlaufen
Python-Code:
| |
Template-Code:
| |
Ausgabe im Browser:
Unsere Produkte
• Apfel
• Birne
• Banane
• Orange
• TraubeSo funktioniert’s:
{% for produkt in produkte %}startet die Schleifeproduktist die Variable für das aktuelle Element{{ produkt }}gibt das aktuelle Element aus{% endfor %}beendet die Schleife
Vergleich zu Python
In Python würdest du schreiben:
| |
In Jinja ist es fast identisch, nur mit {% %} und {% endfor %} am Ende!
Liste mit Styling
| |
| |
Jedes Produkt wird jetzt als schöne Karte angezeigt!
Aufgabe 1: Eigene Liste
- Erstelle eine Route
/hobbys - Definiere eine Liste mit mindestens 5 Hobbys
- Übergebe die Liste ans Template
- Zeige alle Hobbys als nummerierte Liste an (
<ol>)
Index und Nummerierung
Automatische Nummerierung mit loop.index
Jinja bietet dir die spezielle Variable loop, um auf Informationen über die Schleife zuzugreifen:
| |
Ausgabe:
1. Platz 1: Apfel
2. Platz 2: Birne
3. Platz 3: BananeNützliche loop-Variablen
| Variable | Bedeutung | Beispiel |
|---|---|---|
loop.index | Aktuelle Position (ab 1) | 1, 2, 3… |
loop.index0 | Aktuelle Position (ab 0) | 0, 1, 2… |
loop.first | True beim ersten Durchlauf | True/False |
loop.last | True beim letzten Durchlauf | True/False |
loop.length | Anzahl der Elemente | 5 |
Praktisches Beispiel:
| |
Warum loop.index und loop.index0?
loop.indexstartet bei 1 → ideal für Anzeige (“Platz 1”, “Platz 2”)loop.index0startet bei 0 → ideal für Array-Zugriffe oder Berechnungen- Wähle je nach Kontext die passende Variable!
enumerate() aus Python nutzen
Du kennst enumerate() aus Python? In Jinja funktioniert es ähnlich:
| |
| |
Oder einfacher mit loop.index:
| |
Aufgabe 2: Nummerierte Einkaufsliste
Erstelle eine Route /einkaufsliste mit einer Liste von Produkten.
Anforderungen:
- Zeige jeden Eintrag mit Nummer an
- Markiere das erste Produkt mit einer CSS-Klasse
priority - Zeige beim letzten Produkt den Text “(Fertig!)”
- Zeige unterhalb der Liste die Gesamtanzahl an
Listen mit Dictionaries
In echten Anwendungen speicherst du oft mehrere Informationen pro Eintrag. Dafür nutzt du Dictionaries oder Listen von Dictionaries.
Beispiel: Produktliste mit Preisen
| |
| |
Wichtig:
- Auf Dictionary-Werte greifst du mit Punkt-Notation zu:
produkt.name,produkt.preis - Alternative:
produkt['name'],produkt['preis'](wie in Python)
Styling und Interaktivität
| |
Das erstellt abwechselnd verschiedene Styles für gerade/ungerade Produkte!
Aufgabe 3: Kontaktliste
Erstelle eine Route /kontakte mit einer Liste von Personen.
Anforderungen:
- Jede Person hat: Name, E-Mail, Telefon
- Zeige alle Kontakte in einer Tabelle an
- Nutze
{% if %}um E-Mails mit einem mailto-Link zu versehen
Bonus: Färbe jeden zweiten Eintrag anders (mit loop.index % 2)
Verschachtelte Schleifen
Manchmal hast du Listen in Listen - zum Beispiel Kategorien mit mehreren Produkten.
Beispiel: Kategorisierter Shop
| |
| |
Ausgabe:
Obst
• Apfel
• Birne
• Banane
Gemüse
• Tomate
• Gurke
• Paprika
Getränke
• Wasser
• Saft
• TeeKomplexeres Beispiel mit Nummerierung
| |
Äußere und innere Schleife
- Die äußere Schleife durchläuft die Kategorien
- Die innere Schleife durchläuft die Produkte pro Kategorie
- Jede Schleife hat ihre eigene
loop-Variable - Wenn du in der inneren Schleife auf die äußere zugreifen musst, speichere Werte in Variablen
Jinja Filter
Filter verändern die Ausgabe von Variablen. Du wendest sie mit dem Pipe-Symbol | an.
Die wichtigsten Filter
1. length - Anzahl der Elemente
| |
2. upper / lower - Groß-/Kleinschreibung
| |
3. capitalize / title - Erste Buchstaben groß
| |
4. default - Standardwert bei leerem Wert
| |
5. join - Liste zu String verbinden
| |
6. sort - Liste sortieren
| |
Filter kombinieren
Du kannst mehrere Filter hintereinander anwenden:
| |
Praktisches Beispiel
| |
Filter vs Python-Funktionen
Filter in Jinja ähneln Python-Funktionen:
produkte|length≈len(produkte)text|upper≈text.upper()liste|sort≈sorted(liste)
Filter sind aber Template-spezifisch und einfacher zu schreiben!
Leere Listen behandeln
Was passiert, wenn die Liste leer ist? Jinja bietet {% else %} für Schleifen:
| |
Wie es funktioniert:
- Wenn
todosElemente hat → normale Schleife - Wenn
todosleer ist → Inhalt von{% else %}wird angezeigt
Alternativ mit if:
| |
Übungen
Übung 1: Einfache Produktliste
Erstelle eine Route /shop-basic mit einer Liste von mindestens 6 Produkten.
Anforderungen:
- Zeige alle Produkte in einer nummerierten Liste an
- Nutze
loop.indexfür die Nummerierung - Das erste Produkt soll die CSS-Klasse
featuredbekommen - Zeige unterhalb: “Insgesamt X Produkte”
Tipp: Nutze {% if loop.first %} für das erste Element!
Lösung zeigen
1 2 3 4 5# app.py @app.route("/shop-basic") def shop_basic(): produkte = ["Laptop", "Maus", "Tastatur", "Monitor", "Webcam", "Headset"] return render_template("shop_basic.html", produkte=produkte)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18<!-- templates/shop_basic.html --> {% extends "base.html" %} {% block title %}Shop{% endblock %} {% block content %} <h1>Unser Sortiment</h1> <ol> {% for produkt in produkte %} <li class="{% if loop.first %}featured{% endif %}"> {{ loop.index }}. {{ produkt }} </li> {% endfor %} </ol> <p><strong>Insgesamt {{ produkte|length }} Produkte</strong></p> {% endblock %}
1 2 3 4 5 6/* static/style.css */ .featured { color: gold; font-weight: bold; font-size: 1.2em; }
Übung 2: Shop mit Preisen (Tabelle)
Erstelle eine Route /shop-tabelle mit Produkten und Preisen.
Anforderungen:
- Jedes Produkt hat Name und Preis (als Dictionary)
- Zeige alle in einer HTML-Tabelle an
- Produkte unter 10€ sollen grün markiert werden
- Berechne und zeige den Gesamtpreis aller Produkte
Hinweis: Für den Gesamtpreis musst du in Python die Summe berechnen und ans Template übergeben.
Lösung zeigen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15# app.py @app.route("/shop-tabelle") def shop_tabelle(): produkte = [ {"name": "Maus", "preis": 15.99}, {"name": "Tastatur", "preis": 29.99}, {"name": "USB-Kabel", "preis": 5.99}, {"name": "Monitor", "preis": 199.99}, {"name": "Webcam", "preis": 8.99} ] # Gesamtpreis berechnen gesamtpreis = sum(p["preis"] for p in produkte) return render_template("shop_tabelle.html", produkte=produkte, gesamtpreis=gesamtpreis)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33<!-- templates/shop_tabelle.html --> {% extends "base.html" %} {% block content %} <h1>Produktübersicht</h1> <table> <thead> <tr> <th>Nr.</th> <th>Produkt</th> <th>Preis</th> </tr> </thead> <tbody> {% for produkt in produkte %} <tr class="{% if produkt.preis < 10 %}guenstig{% endif %}"> <td>{{ loop.index }}</td> <td>{{ produkt.name }}</td> <td>{{ produkt.preis }} €</td> </tr> {% endfor %} </tbody> <tfoot> <tr> <td colspan="2"><strong>Gesamtpreis:</strong></td> <td><strong>{{ gesamtpreis }} €</strong></td> </tr> </tfoot> </table> <p>{{ produkte|length }} Produkte im Sortiment</p> {% endblock %}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20/* static/style.css */ table { width: 100%; border-collapse: collapse; } th, td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; } .guenstig { background-color: lightgreen; } tfoot { font-weight: bold; background-color: #f0f0f0; }
Übung 3: Verschachtelte Kategorien
Erstelle eine Route /shop-kategorien mit Kategorien und Produkten.
Anforderungen:
- Mindestens 3 Kategorien mit je 3-5 Produkten
- Zeige Kategorien als Überschriften
- Bei jeder Kategorie: Anzahl der Produkte anzeigen
- Produkte als Liste unter jeder Kategorie
- Nutze Filter um Kategorienamen groß zu schreiben
Bonus: Zähle und zeige die Gesamtanzahl aller Produkte (über alle Kategorien).
Lösung zeigen
1 2 3 4 5 6 7 8 9 10 11 12 13# app.py @app.route("/shop-kategorien") def shop_kategorien(): kategorien = { "Elektronik": ["Laptop", "Smartphone", "Tablet", "Kopfhörer"], "Büro": ["Stift", "Papier", "Ordner"], "Gaming": ["Maus", "Tastatur", "Headset", "Controller", "Bildschirm"] } # Gesamtanzahl berechnen gesamt = sum(len(produkte) for produkte in kategorien.values()) return render_template("shop_kategorien.html", kategorien=kategorien, gesamt=gesamt)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21<!-- templates/shop_kategorien.html --> {% extends "base.html" %} {% block content %} <h1>Shop-Kategorien</h1> {% for kategorie, produkte in kategorien.items() %} <div class="kategorie-block"> <h2>{{ kategorie|upper }} ({{ produkte|length }} Artikel)</h2> <ul> {% for produkt in produkte %} <li>{{ produkt }}</li> {% endfor %} </ul> </div> {% endfor %} <hr> <p><strong>Gesamtanzahl aller Produkte: {{ gesamt }}</strong></p> {% endblock %}
1 2 3 4 5 6 7 8 9 10 11 12/* static/style.css */ .kategorie-block { margin-bottom: 30px; padding: 15px; border-left: 4px solid #007bff; background-color: #f8f9fa; } .kategorie-block h2 { color: #007bff; margin-top: 0; }
Zusammenfassung
Das Wichtigste auf einen Blick:
For-Schleifen:
{% for item in liste %}...{% endfor %}- Durchläuft Listen, erzeugt HTML für jedes Element
{% else %}für leere Listen
loop-Variable:
loop.index- Position ab 1loop.index0- Position ab 0loop.first- True beim ersten Elementloop.last- True beim letzten Elementloop.length- Anzahl der Elemente
Dictionaries in Schleifen:
for item in liste_von_dicts- Zugriff:
item.nameoderitem['name'] - Dictionary durchlaufen:
for key, value in dict.items()
Verschachtelte Schleifen:
- Äußere Schleife für Kategorien/Gruppen
- Innere Schleife für Elemente pro Gruppe
- Jede Schleife hat eigene
loop-Variable
Filter:
|length- Anzahl der Elemente|upper/|lower- Groß-/Kleinschreibung|title/|capitalize- Erste Buchstaben groß|sort/|reverse- Sortieren/Umkehren|join(", ")- Liste zu String|default("Wert")- Standardwert bei leer- Filter kombinierbar:
liste|sort|reverse
Häufige Muster:
| |
Nächste Schritte
Jetzt kennst du Schleifen in Jinja! Im nächsten Modul lernst du:
- Komplexe Formulare erstellen
- Daten validieren und speichern
- CRUD-Operationen (Create, Read, Update, Delete)