Flask-Template-Rendering
Das Verketten von HTML-Strings in Python-Code ist sowohl mühsam als auch gefährlich (anfällig für XSS-Schwachstellen). Flask integriert die Jinja2-Template-Engine, um dieses Problem zu lösen.
Vorlagen ermöglichen es Ihnen, Geschäftslogik von der Seitenpräsentation zu trennen und sicheren und wartbareren Code zu schreiben.
render_template-Grundlagen
render_template()Es ist die am häufigsten verwendete Template-Rendering-Funktion in Flask.
Der erste Parameter ist der Name der Template-Datei, und die folgenden Schlüsselwortargumente werden als Variablen an das Template übergeben.
Beispiel
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
# Template templates/index.html rendern, dabei die Variablen title und name übergeben
return render_template("index.html", title=BEISPIEL Startseite, name="World")
@app.route("/user/<username>")
def profile(username):
# Den Benutzernamen aus der URL an das Template übergeben
return render_template("user.html", username=username, posts=[
{"title": Flask-Einführung, "date": "2026-05-01"},
{"title": Jinja2-Vorlage, "date": "2026-05-10"},
])
Template-Dateien werden im Projektverzeichnistemplates/Im Ordner abgelegt:
example-flask-test/
├── app.py
└── templates/
├── index.html
└── user.html
Der Inhalt von index.html ist:
Beispiel (index.html)
<!DOCTYPE html>
<html>
<head>
<title>{{ title }} - BEISPIEL</title>
</head>
<body>
<h1>{{ title }} </h1>
<p>Hallo {{ name }}。</p>
</body>
</html>
Besuchen Siehttp://127.0.0.1:5000/, das Ausgabeergebnis ist:

Jinja2-Grundsyntax
Drei Kern-Syntaxen in Jinja2-Vorlagen:
| Syntax | Zweck | Beispiel |
|---|---|---|
| {{ ... }} | Variablenwerte ausgeben, HTML automatisch escapen | {{ username }} |
| {% ... %} | Kontrollanweisungen (if, for, block, usw.) | {% if user %} |
| {# ... #} | Kommentare, werden nicht im gerenderten Ergebnis angezeigt | {# Dies ist ein Kommentar #} |
Vorlagenbeispiel
Beispiel (user.html)
<!DOCTYPE html>
<html>
<head>
<title>{{ username }} - BEISPIEL</title>
</head>
<body>
<h1>Persönliche Homepage von {{ username }}</h1>
<!-- Bedingung: Wenn die posts-Liste leer ist, eine Hinweismeldung anzeigen -->
{% if posts %}
<h2>Neueste Artikel:</h2>
<ul>
<!-- Schleife über die posts-Liste -->
{% for post in posts %}
<!-- loop.index ist eine integrierte Jinja2-Variable, beginnend bei 1 -->
<li>{{ loop.index }}. {{ post.title }} ({{ post.date }})</li>
{% endfor %}
</ul>
{% else %}
<p>Noch keine Artikel</p>
{% endif %}
<!-- Verwenden des Filters: upper wandelt Text in Großbuchstaben um -->
<p>Benutzername in Großbuchstaben: {{ username|upper }}</p>
</body>
</html>
Gängige Filter
Filter werden verwendet, um das Ausgabeformat von Variablen mithilfe des Pipe-Symbols zu ändern.|Aufruf.
| Filter | Funktion | Beispiel | Ausgabe |
|---|---|---|---|
| upper | In Großbuchstaben umwandeln | {{ "hello"|upper }} | HELLO |
| lower | In Kleinbuchstaben umwandeln | {{ "HELLO"|lower }} | hallo |
| title | Ersten Buchstaben groß schreiben | {{ "hello world"|title }} | Hello World |
| length | Länge abrufen | {{ [1,2,3]|length }} | 3 |
| default | Standardwert festlegen | {{ name|default("anonymous") }} | Anonym (wenn name leer ist) |
| safe | Als sicheres HTML markieren (kein Escaping) | {{ "Fett"|safe }} | Als fetter Text gerendert |
| join | Liste zusammenfügen | {{ ["a","b"]|join(",") }} | a,b |
Sicherheitswarnung:safeDer safe-Filter deaktiviert Auto-Escaping; verwenden Sie ihn nur, wenn Sie der Datenquelle absolut vertrauen. Verwenden Sie ihn niemals für Benutzereingaben.safe。
Auto-Escaping — XSS-Schutz
Jinja2 maskiert HTML standardmäßig bei allen Variablenausgaben; dies ist eine wichtige Verteidigung für die Websicherheit.
Wenn der vom Benutzer übermittelte Benutzername beispielsweise<script>alert("xss")</script>ist, wird er beim Rendern der Vorlage automatisch in sicheren Text umgewandelt:
<!-- 模板中直接使用变量 -->
<p>{{ username }}</p>
<!-- 渲染结果(HTML 特殊字符已被转义) -->
<p>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</p>
Maskierung gilt für.html、.htm、.xml、.xhtml、.svgDie Vorlagendatei am Ende.
Template-Vererbung — doppelten Code vermeiden
Template-Vererbung ist eine der leistungsstärksten Funktionen von Jinja2. Sie ermöglicht es Ihnen, ein "Basislayout" zu definieren und dann Inhalte über untergeordnete Templates einzufügen.
Dadurch wird vermieden, dass gemeinsame Teile wie Header, Navigation, Fußzeilen usw. auf jeder Seite wiederholt geschrieben werden.
Basis-Template (übergeordnetes Template)
Beispiel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}BEISPIEL Flask-Tutorial{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header>
<h1>BEISPIEL Flask-Tutorial</h1>
<nav>
<a href="/">Startseite</a> |
<a href="/about">Über uns</a>
</nav>
</header>
<main>
<!-- Block ist ein Platzhalterbereich, den untergeordnete Templates füllen oder überschreiben können -->
{% block content %}{% endblock %}
</main>
<footer>
<p>© 2026 example.com</p>
</footer>
</body>
</html>
Untergeordnetes Template (erbt von übergeordnetem Template)
Beispiel
{% extends "base.html" %}
<!-- Überschreibt den title-Block des übergeordneten Templates -->
{% block title %}EXAMPLE Tutorial - Startseite{% endblock %}
<!-- Füllt den content-Block des übergeordneten Templates -->
{% block content %}
<h2>Willkommen bei EXAMPLE</h2>
<p>{{ greeting }}</p>
{% if user %}
<p>Aktueller Benutzer: {{ user }}</p>
{% else %}
<p><a href="/login">Bitte melden Sie sich zuerst an</a></p>
{% endif %}
{% endblock %}
| Tags | Funktion |
|---|---|
| {% extends "base.html" %} | Deklarieren Sie, dass das aktuelle Template von base.html erbt (muss in der ersten Zeile stehen) |
| {% block name %}...{% endblock %} | Definiere einen Block, der von untergeordneten Templates überschrieben werden kann |
| {{ super() }} | Rufe den Inhalt des gleichnamigen Blocks des übergeordneten Templates innerhalb des Blocks des untergeordneten Templates auf. |
Nach der Verwendung von Template-Vererbung müssen Sie nurbase.htmlan einer Stelle ändern, und die gemeinsamen Teile aller Seiten (wie Navigation, Footer) werden automatisch aktualisiert.
Eingebaute Objekte in Templates
Die folgenden Flask-Objekte können direkt in Templates verwendet werden, ohne dass sie überrender_template()übergeben werden:
| Objekt | Beschreibung | Verwendungsbeispiel im Template |
|---|---|---|
| request | Aktuelles Anfrageobjekt | {{ request.path }} |
| session | Aktuelle Sitzungsdaten | {{ session.get("username") }} |
| g | Globale Variablen auf Request-Ebene | {{ g.user }} |
| config | Anwendungskonfiguration | {{ config["APP_NAME"] }} |
| url_for() | URL-Generierungsfunktion | {{ url_for("index") }} |
| get_flashed_messages() | Flash-Nachrichten abrufen | {% for msg in get_flashed_messages() %}... |
Andere Templates einbinden — include
Verwendung{% include %}Du kannst ein anderes Template innerhalb eines Templates einbetten:
Beispiel
<nav style="background:#f0f0f0;padding:10px;">
<a href="/">Startseite</a> |
<a href="/posts">Artikel</a> |
<a href="/about">Über uns</a>
</nav>
Beispiel
<!DOCTYPE html>
<html>
<head><title>Seite</title></head>
<body>
{% include "_navbar.html" %}
<h1>Seiteninhalt</h1>
<p>Dies ist der Hauptinhalt der Seite.</p>
</body>
</html>
Bewährte Praktiken: Template-Vererbung (extends) wird für die Wiederverwendung von Layouts auf Seitenebene verwendet,includeWird für die Wiederverwendung von Code auf Komponentenebene verwendet. Wiederverwendbare Komponenten wie Navigationsleisten und Seitenleisten eignen sich für include.
Vollständiges Beispiel: Blog-Startseite
Integrieren Sie das oben Gelernte in ein reales Szenario:
Beispiel
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
# Artikeldaten in der Datenbank simulieren.
articles = [
{"id": 1, "title": Flask-Einstiegsanleitung, "author": "example", "views": 1024},
{"id": 2, "title": Jinja2-Templates erklärt, "author": "admin", "views": 512},
{"id": 3, "title": RESTful-API-Design, "author": "example", "views": 256},
]
return render_template("blog.html", articles=articles)
Beispiel
{% extends "base.html" %}
{% block title %}Beispiel-Blog{% endblock %}
{% block content %}
<h2>Neueste Artikel</h2>
{% if articles %}
{% for article in articles %}
<!-- Unterschiedliche Stile je nach Aufrufzahl hinzufügen -->
<div class="article" {% if article.views > 1000 %}style="background:#fff3cd;"{% endif %}>
<h3>{{ article.title }}</h3>
<p>Autor: {{ article.author }} | Aufrufe: {{ article.views }}</p>
<!-- Verwende die loop-Variable, um ein Trennzeichen zu erstellen -->
{% if not loop.last %}
<hr>
{% endif %}
</div>
{% endfor %}
{% else %}
<p>Noch keine Artikel, bitte schau später wieder vorbei.</p>
{% endif %}
{% endblock %}
Spezielle Jinja2-Variablen
| Variable | Beschreibung |
|---|---|
| loop.index | Aktueller Schleifenindex, beginnt bei 1 |
| loop.index0 | Aktueller Schleifenindex, beginnt bei 0 |
| loop.first | Gibt an, ob es die erste Iteration der Schleife ist |
| loop.last | Gibt an, ob es die letzte Iteration der Schleife ist |
| loop.length | Gesamtlänge der Sequenz |