Hello, Flask

Lernziele

  • Erstellen Sie eine einfache Flask-Anwendung, um ein Verständnis dafür zu entwickeln, wie man dieses Framework verwendet.
  • Machen Sie sich mit Jinja vertraut, einer Template-Sprache, die in Verbindung mit Flask genutzt wird.

flask-logo

Hintergrund

Flask, ein Microframework für die Webentwicklung, kann zu Beginn verwirrend sein. Es gibt mehrere Dateien unterschiedlichen Typs, die in bestimmten Ordnern abgelegt werden müssen. In diesem Problem beginnen wir mit dem absoluten Minimum – einer einzelnen Python-Datei. Von dort aus werden wir den nächsten Schritt machen und unsere erste vollwertige Webanwendung erstellen!

Bevor Sie beginnen

Öffnen Sie VS Code entsprechend Ihrem Setup, klicken Sie auf Ihr Terminalfenster und führen Sie cd aus. Die Eingabeaufforderung Ihres Terminalfensters sollte ungefähr wie folgt aussehen:

$

Führen Sie den Befehl

wget https://inf.zone/download/exercises/09/helloflask.zip

aus, um in Ihrem Codespace die ZIP helloflask.zip herunterzuladen.

Nun können Sie

unzip helloflask.zip

ausführen, um die ZIP in den Ordner helloflask zu entpacken.

Sie benötigen die ZIP-Datei nicht mehr, daher können Sie den Befehl

rm helloflask.zip

ausführen und bei der Aufforderung mit „y“ gefolgt von der Eingabetaste antworten, um die heruntergeladene ZIP-Datei zu entfernen.

Geben Sie nun den Befehl

cd helloflask

ein und drücken Sie anschließend die Eingabetaste, um in dieses Verzeichnis zu wechseln (d. h., es zu öffnen). Ihre Eingabeaufforderung sollte nun wie folgt aussehen:

helloflask/ $

Implementierungsdetails

Die einfachste Flask-Anwendung verwendet nur eine Datei, app.py. Diese erstellt eine HTML-Seite und sagt “Hallo”. Fügen Sie Folgendes in app.py ein, um zu beginnen:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello, World!"

Dieser Code beginnt damit, Flask aus der flask-Bibliothek zu importieren. Flask ist eine Klasse (siehe Short zum Objektorientierten Programmieren. Es reicht vorerst zu sagen, dass es wie eine Vorlage für die Anwendung ist, die wir erstellen werden. Die Zeile app = Flask(__name__) weist Python an, eine bestimmte Anwendung zu erstellen, die, basierend auf der Vorlage, fortan „app“ genannt wird. Um die spezifische Anwendung zu erstellen, übergeben wir der Flask-Klasse den Namen der aktuellen Python-Datei (repräsentiert durch __name__), was es unserer Anwendung ermöglicht, später hinzugefügte Dateien zu finden. In diesem Fall heißt die Datei ebenfalls „app“, um konsistent zu bleiben.

Die mysteriöseste Zeile in der von Ihnen geschriebenen Anwendung ist wahrscheinlich die, in der Sie folgendes geschrieben haben:

@app.route("/")

Diese Art von Funktion wird als Dekorator bezeichnet. Dekoratoren ermöglichen es, eine grundlegende Funktion wie app.route zu nehmen und deren Funktionalität mit etwas Eigenem zu erweitern: der Funktion, die Sie nach dem Dekorator schreiben. Wenn Sie mehr über Dekoratoren erfahren möchten, können Sie entsprechende Ressourcen dazu lesen oder das Short zum Objektorientierten Programmieren ansehen (@property ist auch ein Decorator).

Diese Zeile teilt Flask mit, dass, wenn eine HTTP-Anfrage für „/“ eingeht, die Funktion index ausgeführt werden soll. Beachten Sie, dass, wenn wir die Funktion in homepage umbenennen würden, diese Zeile Flask mitteilen würde, dass es, jedes Mal, wenn es eine HTTP-Anfrage für „/“ erhält, die Funktion homepage ausführen soll.

Beachten Sie, dass die Funktion index ein Textstück, nämlich „Hello, World!“, zurückgibt. Dieser Text wird dem Benutzer von Flask angezeigt, sobald ihre Anfrage an die „/“-Route abgeschlossen ist. Statt eines einfachen Textstücks könnte die Funktion auch den Inhalt einer vollständigen HTML-Datei zurückgeben, die der Browser entsprechend rendern würde – dies ist in der Praxis häufig der Fall. Der Einfachheit halber beschränken wir uns jedoch zunächst auf diesen kurzen Text.

Um Ihre Anwendung auszuführen, geben Sie flask run in das Terminal ein, und Sie erhalten einen Link, auf den Sie klicken können, ähnlich wie bei der Ausführung von http-server. Sie haben eine Flask-Anwendung geschrieben! Versuchen Sie, einen anderen Text zurückzugeben, wie <h1>Hello, World!</h1>. Wie verändert sich das, was Sie sehen?

Templates

Anstatt HTML-Code direkt in unsere Python-Programme einzufügen, ist es am besten, unser HTML in separate Dateien auszulagern, um die verschiedenen Aufgaben zu trennen. Da unsere App wahrscheinlich eine Reihe ähnlicher HTML-Dateien beinhalten wird, können wir eine Datei namens layout.html erstellen, die alle unsere HTML-Dateien „erweitern“. Das „Erweitern“ einer HTML-Datei bedeutet, dass der gesamte Inhalt dieser HTML-Datei beibehalten wird, während zusätzlich benutzerdefinierter Inhalt eingefügt wird, der spezifisch für eine bestimmte Seite ist.

Nach Konvention speichert Flask alle HTML-Dateien in einem Ordner namens templates. Erstellen Sie im Ordner helloflask einen Ordner namens templates, indem Sie mkdir templates ausführen. Alle Ihre HTML-Dateien werden in diesem Ordner abgelegt.

Erstellen Sie im Ordner templates eine Datei namens layout.html, die wie folgt aussieht:

<!DOCTYPE html>

<html lang="de">
    <head>
        <title>Hallo, Flask</title>
    </head>
    <body>
        <h1>Hallo, Flask</h1>
        {% block body %}{% endblock %}
    </body>
</html>

Die Syntax {% block body %}{% endblock %} stammt von Jinja, einer „Template-Engine“ für Python. Die Zeile mit {% block body %}{% endblock %} macht diese Datei zu einer Layout-Datei. Wenn eine andere HTML-Datei die Datei layout.html erweitert und einen Block namens „body“ definiert, wird dieser Block an dieser Stelle in der layout.html eingefügt. Eine Layout-Datei kann so viele Blöcke enthalten, wie man möchte. Geben Sie einfach jedem Block einen anderen Namen.

Erstellen Sie nun eine Datei index.html, die das Template layout.html wie folgt erweitert:

{% extends "layout.html" %}

{% block body %}
    <p>Als Nächstes fügen wir hier ein Formular ein und erhalten eine POST-Aktion!</p>
{% endblock %}

Zuletzt kehren wir zu app.py zurück, um diese Änderungen umzusetzen. In den anfänglichen Importen benötigen wir einige weitere Funktionen aus Flask (wie unten gezeigt). Ersetzen Sie dann die direkte Rückgabe von Text durch einen Aufruf der Funktion render_template von Flask. Der Zweck der Funktion render_template ist es, index.html so vorzubereiten, dass sie beim Übergeben an den Browser auch das HTML enthält, das sie von layout.html „erbt“.

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html")

Wenn Sie nun Ihre Anwendung ausführen (geben Sie flask run ein), wird Ihre App ein wenig strukturierter. Aber sie ist noch nicht wirklich interaktiv!

Forms

HTML-Forms ermöglichen es dem Benutzer, Daten in Eingabefelder einzugeben und diese Daten an den Server zu senden, häufig unter Verwendung der POST-Methode des HTTP-Protokolls. Weitere Informationen zu HTML-Forms finden Sie hier.

Fügen Sie ein Form zu index.html hinzu, sodass es wie folgt aussieht:

{% extends "layout.html" %}

{% block body %} 
    <form action="/" method="post"> 
        Was ist Ihre Lieblingsfarbe? 
        <select name="color"> 
            <option value="red">Harvard Crimson</option> 
            <option value="blue">Yale Blue</option> 
        </select> 
        <button type="submit">Absenden</button> 
    </form> 
{% endblock %}

Beachten Sie, dass jedes Formularelement sowohl einen name als auch ein value hat. Der Name eines Elements ist das, worüber wir dieses Element ansprechen werden. Sein Wert ist der Wert, der vom Formular übermittelt wird. Jeder dieser Werte wird an app.py übergeben, damit wir ihn beim Absenden des Formulars nutzen können.

Führen Sie Ihre Anwendung aus, besuchen Sie die /-Route und senden Sie das Formular ab. Ups! Sie sollten die Nachricht „Methode nicht erlaubt“ sehen. Daher müssen wir zunächst sicherstellen, dass Flask die Verwendung der POST-Methode auf / zulässt.

POST

In der Datei app.py müssen wir unsere Route anpassen, um die POST-Anfrage zu verarbeiten. So sieht unser neues app.py aus:

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("index.html")
    else:
        print("Formular wurde abgesendet!")
        color = request.form.get("color")
        return render_template("color.html", color=color)

Dieses Beispiel enthält einige Logik: Wenn der Benutzer eine GET-Anfrage sendet, zeigen wir ihm das grundlegende index.html mit einem Formular zum Absenden. Wenn jedoch eine POST-Anfrage gesendet wird, tun wir einige unterschiedliche Dinge:

  • Wir geben die Nachricht „Formular wurde abgesendet!“ in der Konsole aus, um das Debuggen zu erleichtern. Wir sollten dies später entfernen, wenn wir sicher sind, dass unser Programm wie gewünscht funktioniert.
  • Der Wert der „color“-Eingabe wird in einer Variablen mit dem gleichen Namen gespeichert, also mit color = request.form.get("color").
  • Eine neue HTML-Datei, color.html, wird gerendert und der Wert der color-Variablen wird unter dem gleichen Namen in die Datei übergeben.

Erstellen wir nun color.html, damit unsere Anwendung funktioniert:

{% extends "layout.html" %}

{% block body %}
    <p style="color: {{ color }}">Ihre Lieblingsfarbe ist {{ color }}.</p>
{% endblock %}

Beachten Sie, wie wir den Wert von color an jeder beliebigen Stelle in unserem HTML einfügen können – sei es als Text in einem Satz oder als Platzhalter für den Wert einer CSS-Eigenschaft.

Wir möchten jedoch wahrscheinlich eine zusätzliche Eingabevalidierung hinzufügen, anstatt einfach darauf zu vertrauen, dass unsere Benutzer nur die Farben „blau“ oder „rot“ über POST senden. Welchen zusätzlichen Code könnten Sie hinzufügen, um sicherzustellen, dass die Farben, die wir erhalten, gültige Farben sind?

Testen

Ihr Programm sollte sich gemäß den oben genannten Beispielen verhalten.

Für diese Aufgabe gibt es kein check50!