Flask – Python – Templates und Forms

In diesem Beitrag geht es weiter mit dem Webframework Flask für Python und es werden folgende Themen behandelt: Templates und Forms in Flask.

Mit Flask ist es möglich sogenannte Template-Files zu verarbeiten und für unsere Webapps zu nutzen. Flask nutzt dafür die Template-Engine Jinja2. Diese Engine sorgt für die Verarbeitung und Interpretation der Template-Dateien.

Was sind Templates bei Flask?

Als Templates werden in diesem Fall spezielle HTML-Dateien bezeichnet, die zusätzlich zum HTML-Code weitere Platzhalter beinhalten. An diese Stellen können wir als Entwickler, über unser Python Skript, Inhalt einsetzen und diesen verändern (während der Laufzeit). Damit lässt sich eine Interaktion mit dem Benutzer unserer Webapp realisieren.

Zum Beispiel könnte der Benutzer einen Button klicken, woraufhin sich die angezeigte HTML-Seite verändert und den Inhalt einer Variablen aus unserem Code als Text ausgibt. Dabei wird dann einfach ein Platzhalter in der Datei ersetzt.

Ein einfaches Beispiel:

<html>
   <body>
      <p>Hallo {{ name }}, wie gehts?</p>
   </body>
</html>

Wir speichern die Datei als „Willkommen.html“ in unserem Templates-Ordner ab.

Die geschweiften Klammern definieren den Platzhalter + Namen. Hierbei sind es zwei geschweifte Klammern hintereinander, was bedeutet, dass die Engine dort einfachen Text einsetzt und dieser ausgeben wird.

Das dazugehörige Skript:

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/willkommen/<nutzername>')
def Willkommen(nutzername):
   return render_template('Willkommen.html', name = nutzername)

if __name__ == '__main__':
   app.run(debug = True)

Die Methode „render_template()” verarbeitet unsere Template-Datei und kann, anhand des zweiten Parameters, den Platzhalter „name“ in der Datei mit dem Inhalt von „nutzername“ ersetzen. Den Inhalt von „nutzername“ ändern wir über den Pfad bzw. die URL, über die wir unsere Webapp aufrufen. Rufen wir z.B. den Pfad http://127.0.0.1:5000/willkommen/Stani auf, dann würde

<p>Hallo Stani, wie gehts?</p>  in der HTML-Datei eingesetzt werden. Die Variable im Pfad wird mit spitzen Klammern angegeben.

Die Template-Engine bietet aber noch mehr und ermöglicht es uns Expressions (Ausdrücke) in unsere HTML-Dateien einzubauen. So können wir z.B. ein If-Statement in die Datei einsetzen und damit auf unterschiedliche Variablen-Werte reagieren. Auch Schleifen lassen sich einbauen. Für diese Art von Ausdrücken nutzen wir nun eine alternative Schreibweise für den Platzhalter:

{% for … %}
Code
{% endfor %}

{% if variable==10 %}
Code
{% else %}
Code
{% endif %}

Ein kleines Beispiel auch dieser Art von Templates.

from flask import Flask, render_template
app = Flask(__name__)
Autos = [ 
	{
		'modell': 'S600',
		'marke': 'Mercedes-Benz',
		'baujahr': '2013',
		'ps': '530'
	},
	{
		'modell': 'GTR',
		'marke': 'Nissan',
		'baujahr': '2016',
		'ps': '570'
	},
]

@app.route(„/daten“)
def daten():
	return render_template(‘autos.html’, Autos = Autos)

Dazugehörige HTML-File:

<html>
   <head>
   </head>
   <body>
      {% for auto in Autos %}
	 <h1> {{ auto.modell }}
         <p> Marke: {{ auto.marke }} , Baujahr: {{ auto.baujahr }} </p>
         <p> PS: {{ auto.ps }} </p>
       {% endfor %}
   </body>
</html>

In diesem Beispiel wird eine Liste von Sets mit Daten zu verschiedenen Autos durchgegangen und in der HTML-Datei ausgegeben.

Webforms mit Flask

Nachdem wir Templates behandelt haben, kommen wir nun zu einem Thema, das auf Templates aufbaut und uns weiterführende Möglichkeiten eröffnet unsere Webapps zu gestalten.

Um dem Nutzer eine Interaktion zu ermöglichen, die nicht nur in Form von der Anpassung eines URL-Pfads besteht, benötigen wir komplexere Objekte wie z.B. Buttons, Text-Felder usw.

Diese Steuerelemente werden in einer Seite oder einer Eingabemaske zusammengeführt. Diese Seite bzw. grafische Oberfläche wird als Webform bezeichnet.

WTForms

Zur Umsetzung von Webforms empfehle ich euch das Modul „wtforms“ für Flask.

pip install wtforms

Zuallererst benötigen wir einen sogenannten „Secret-Key“ für unsere App. Dieser wird für die Erstellung von Webforms von wtforms vorausgesetzt und dient zur Sicherung der Client-Session.

app.config[„SECRET-KEY“] = "Mediasuche"

Nun legen wir für unser Webform eine eigne Klasse an. Diese erbt von FlaskForm und enthält die Eingabefelder und einen Button zum Absenden der Daten. Die Felder und der Button werden über Objekte aus wtforms erzeugt. Z.B StringField für einfache Textfelder oder SubmitField für Buttons zum Absenden/Bestätigen.

In unserer dazugehörige HTML-Datei legen wir den Aufbau des Forms fest. Über Template-Platzhalter können wir auf die einzelnen Elemente unserer Form Klasse zugreifen und diese einbauen.

Mit den Optionen method = „POST“ und action = „/register“ verknüpfen wir unser Form mit dem Pfad /register und legen fest, dass wir eine POST-Anfrage über das Form erhalten werden.

<html>
<head></head>
<body>
    <form method="POST" action="/register">
        {{ form.vorname.label }} {{ form.vorname() }}
        <br><br>
        {{ form.nachname.label }} {{ form.nachname() }}
        <br><br>
        {{ form.submit() }}
    </form>

</body>
</html>

Nachdem wir unsere HTML-Seite fertiggestellt haben, müssen wir unsere angelegte Form-Klasse mit dem gleichen Pfad „/register“ zuweisen. Dies geschieht über die „route“-Funktion unseres App-Objektes (wie wir es bereits kennen). Hierbei setzen wir als Parameter zusätzlich die Variable „methods“ ein und weisen dieser „POST“ und „GET“ zu. Dies bewirkt das Gleiche wie die Option method = „POST“ in unserer Template-Datei. In der Methode zum Pfad erzeugen wir eine Instanz unserer Webform-Klasse. Diese Instanz wird in der render_template()

Methode genutzt, um die Daten der Webform mit den Plathaltern der Template-Datei zu verknüpfen.

Zur Abfrage, ob unser Button geklickt wurde, fügen wir die Funktion form.validate.on_submit() ein. Damit können wir festlegen, was passiert, wenn der Absenden-Button geklickt wurde. Z.B. Wie die eingegeben Daten verarbeitet/interpretiert werden.

app.config["SECRET_KEY"] = 'Mediasuche'

class nameform(FlaskForm):
   vorname = StringField('Vorname')
   nachname = StringField('Nachname')

   submit = SubmitField('Absenden')

@app.route('/register' , methods=['POST','GET'])
def register():
   form = nameform()
   if form.validate_on_submit():
      return "abc"
   return render_template('register.html',form = form)

if __name__ == '__main__':
   app.run(debug = True)

Validators in WTForms

Wtforms bietet uns aber noch einiges mehr. Über Validators können wir zu den Text-Feldern zusätzliche Überprüfungen und Abfragen einsetzen. Damit ist es z.B. möglich, zu überprüfen, ob ein Feld leer gelassen wurde oder ob ein Feld eine bestimmte Anzahl an Zeichen überschritten hat.

Username = StringField('username', validators = [InputRequierd(), Length(min=10,max=20)]

Bootstrap mit WTForms

Mit WTForms ist es möglich das Bootstrap-Framework zu nutzen und für die Gestaltung der Steuerelemente einzubinden. Dafür müssen wir zu erst einmal Bootstrap „importieren“. Dies tun wir in zwei Schritten: Zuerst importieren wir das flask_bootstrap-Modul in unsere Python-Datei und initialisieren mit Bootstrap(app) unser App-Objekt, sodass wir Bootstrap hierfür verwenden können. Als zweiten Schritt importieren Bootstrap in unsere Template-File.

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

Damit wir Bootstrap korrekt für unsere Template-File verwenden können, müssen wir diese verändern und anpassen. Wir nutzen nun Blöcke, um unsere HTML-Anweisungen zu gliedern. Das bedeutet, dass wir Platzhalter-Anweisungen wie z.B. {% block content %} nutzen, um festzulegen, dass eine HTML-Anweisung im Body-Teil steht. Die normale Gliederung von HTML entfällt hiermit und wir durch eine Alternative Aufbauweise ersetzt, die von der Template-Engine interpretiert werden kann. Hier ist eine Liste von den einzelnen Block-Typen und wofür sie eingesetzt werden.

Bootstrap Starter Kit

Kollektion von mehreren Bootstrap Content-Blocks, mit denen ihr eure Website designen könnt. Responsive Webseiten gestalten mithilfe von Bootstrap und dem Starter Kit. .

Außerdem nutzen wir die Methode form_field von unserem Objekt „wtf“ aus der Import-Anweisung, um die Variablen der Steuerelemente festzulegen.

So würde die Bootstrap basierte Template-File aussehen:

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block content %}
<div class="container">
    <dl>
      <form method="POST" action="/register">
       {{ wtf.form_field(form.vorname) }}
       <br><br>
       {{ wtf.form_field(form.nachname) }}
       <br><br>
       <input class ="btn btn-primary" type="submit" value="Absenden">
      </form>
    </dl>
</div>
{% endblock %}


Wer sich weitergehend informieren möchte und mehr über die Entwicklung mit Flask lernen möchte, kann sich dieses Buch ansehen. Hier wird in 18 Kapiteln jedes Detail des Frameworks durchleuchtet und anhand von guten und anschaulichen Beispielen erklärt.

, , , , markiert

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Dies ist ein Demo-Shop für Testzwecke — Bestellungen werden nicht ausgeführt. Ausblenden