3. diel - WTForms a Jinja2 šablóny pre Flask framework
V minulej lekcii, Zoznámenie s Flask microframeworkem , sme si vytvorili aplikáciu Kalkulačka, aby sme si ukázali, ako fungujú formuláre a ako z nich získať dáta. V dnešnom Python tutoriále si ukážeme, ako vytvoriť formulár ešte lepšie pomocou knižnice WTForms. Tie podporujú napr. Automatické validácie na strane servera alebo ochranu proti CSRF útoku. To sú pomerne základné funkcie, ktoré od formulárov u aplikácií požadujeme, a preto budeme knižnicu aj naďalej používať.
WTForms
Aby sme si mohli vôbec nejaký ten formulár vytvoriť, musíme si toto "rozšírenie" nainštalovať pomocou nástroja pip:
py -m pip install flask-wtf
Ak inštalácia WTForms prebehla úspešne, uvidíte výstup podobný tomuto:
C:\Users\David>py -m pip install flask-wtf Collecting flask-wtf Downloading https://files.pythonhosted.org/packages/60/3a/58c629472d10539ae516 7dc7c1fecfa95dd7d0b7864623931e3776438a24/Flask_WTF-0.14.2-py2.py3-none-any.whl Requirement already satisfied: Flask in c:\users\david\appdata\local\programs\py thon\python36-32\lib\site-packages (from flask-wtf) Collecting WTForms (from flask-wtf) Downloading https://files.pythonhosted.org/packages/9f/c8/dac5dce9908df1d9d48e c0e26e2a250839fa36ea2c602cc4f85ccfeb5c65/WTForms-2.2.1-py2.py3-none-any.whl (166 kB) 100% |████████████████████████████████| 174kB 2.2MB/s Requirement already satisfied: Jinja2>=2.10 in c:\users\david\appdata\local\prog rams\python\python36-32\lib\site-packages (from Flask->flask-wtf) Requirement already satisfied: click>=5.1 in c:\users\david\appdata\local\progra ms\python\python36-32\lib\site-packages (from Flask->flask-wtf) Requirement already satisfied: Werkzeug>=0.14 in c:\users\david\appdata\local\pr ograms\python\python36-32\lib\site-packages (from Flask->flask-wtf) Requirement already satisfied: itsdangerous>=0.24 in c:\users\david\appdata\loca l\programs\python\python36-32\lib\site-packages (from Flask->flask-wtf) Requirement already satisfied: MarkupSafe>=0.23 in c:\users\david\appdata\local\ programs\python\python36-32\lib\site-packages (from Jinja2>=2.10->Flask->flask-w tf) Installing collected packages: WTForms, flask-wtf Successfully installed WTForms-2.2.1 flask-wtf-0.14.2 C:\Users\David>
Použijeme aplikáciu z minulej lekcie s tým rozdielom, že formulár vytvoríme pomocou WTForms:
# Importujeme from flask_wtf import FlaskForm from wtforms import SelectField, IntegerField, widgets app = Flask(__name__) # Musíme nastavit SECRET_KEY, pokud chceme používat CSRF app.config["SECRET_KEY"] = "super tajny klic" class MujFormular(FlaskForm): prvni_cislo = IntegerField("První Číslo", widget = widgets.Input(input_type = "number")) operator = SelectField("Operátor", choices=[("+" ,"+"), ("-", "-"), ("*", "*"), ("/", "/")]) druhe_cislo = IntegerField("Druhé Číslo", widget = widgets.Input(input_type = "number")) @app.route("/", methods = ["GET", "POST"]) def kalkulacka(): form = MujFormular() if form.validate_on_submit(): prvni_cislo = form.prvni_cislo.data druhe_cislo = form.druhe_cislo.data operator = form.operator.data vysledek = eval( str(prvni_cislo) + operator + str(druhe_cislo) ) return render_template("template.html", vysledek = vysledek, form = form) return render_template("template.html", form = form)
Najprv si vytvoríme triedu MujFormular
, potom vytvoríme 3
políčka. U políčok je prvým parametrom popis, ktorý môžeme zobraziť
pomocou Jinja2 šablón. Ďalej nastavíme inputům s číslom widget s typom
number
(rovnaké ako napísať
<input type="number">
) a SelectField
má ako
ďalší argument pole, ktoré obsahuje dvojice value
a
text
, ktoré sa zobrazia na stránke k výberu. Všimnite si
rozšírenie konfigurácie aplikácie o ochranu proti podvrhnutí formulára cez
útok CSRF.
Následne si vytvoríme inštanciu formulára, ktorý si automaticky vezme dáta z requestu. Potom skontrolujeme, či bol formulár odoslaný a vykonáme validáciu dát. Ak všetko prebehlo úspešne, dáta načítame a vrátime výsledok.
Upravíme náš template a pridáme vygenerovaný formulár.
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body> <form method="POST"> {{ form.hidden_tag() }} {{ form.prvni_cislo }} {{ form.operator }} {{ form.druhe_cislo }} <input type="submit"> </form> <hr> Výsledek: {% if vysledek %} {{ vysledek }} {% else %} Vyplň formulář {% endif %} </body> </html>
Najskôr vykreslíme všetky skryté tagy. Keďže žiadne nemáme, načíta sa iba CSRF token, ktorý nášmu formuláru poskytuje ochranu proti podvrhnuté. Potom načítame ostatné vstupné polia.
Aktuálne sa nám budú overovať iba numerické polia, ak obsahujú číslo,
a polia s operátorom, či obsahuje jeden zo znakov /*-+
. To nám
nestačí a chceme vypísať aj chybovú hlášku ku každému inputu. Kód teda
ešte upravíme:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body> <form method="POST"> {{ form.hidden_tag() }} {{ form.prvni_cislo }} {{ form.operator }} {{ form.druhe_cislo }} <input type="submit"> </form> {% for field, errors in form.errors.items() %} {% for error in errors %} <span style="color: red;">Chyba pole - {{ field }} hláška - {{ error }}</span><br> {% endfor %} {% endfor %} <hr> Výsledek: {% if vysledek %} {{ vysledek }} {% else %} Vyplň formulář {% endif %} </body> </html>
Chybová hláška vyzerá takto:
Tvorba hlavnej šablóny
Býva zvykom, že webová aplikácia má nejakú hlavnú šablónu (rozloženie s navigačným menu, hlavičkou, pätičkou a pozadím) a jednotlivé podstránky sa potom vykresľujú dovnútra. Poďme tak urobiť aj u kalkulačky.
Najprv si vytvoríme šablónu stránky. Pre náš účel stačí niečo
jednoduché, pokojne si motív potom upravte podľa ľubovôle. Vytvoríme si
šablónu base.html
, ktorú vložíme do zložky
root/templates/
. Kód bude mať nasledujúce:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Můj web ve Flasku</title> <style> html, body{ margin: 0; } #content{ margin: auto; max-width: 75%; min-height: 500%; border: solid; border-color: black; border-width: 2px; border-radius: 15px; padding: 100px; font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif; } header{ min-height: 100px; min-width: 100%; background-color: #569ee2; margin-bottom: 50px; font-family: Arial Black; } footer{ position: absolute; bottom: 0; min-height: 120px; min-width: 100%; background-color: #569ee2; font-family: Arial Black; } </style> </head> <body> <header> {% block header %} Zde není nic zajímavého {% endblock %} </header> <div id="content"> {% block content %} {% endblock %} </div> <footer> {% block footer %} Prostý footer {% endblock %} </footer> </body> </html>
Všimnite si, že sme si tu definovali bloky header
,
content
a footer
a do blokov header
a
footer
sme vložili nejaký text. Ten sa zobrazí na stránke
dedičov z tejto šablóny (teda podstránke) iba ak blok nepoužijeme alebo
Jinja2 donútime vyrenderovať obsah pomocou {{ super() }}
.
Všetko je vidieť z nasledujúcej úpravy template.html
, ktorý
teraz dedí z tohto hlavného a vykresľuje sa teda do neho. Obsahuje už len
HTML kód potrebný pre danú podstránku s kalkulačkou a je kratšia:
{% extends "base.html" %} {% block header %} Zde je něco zajímavého<br> {{ super() }} {% endblock %} {% block content %} <form method="POST"> {{ form.hidden_tag() }} <table> <tr><td>{{ form.prvni_cislo.label }}:</td><td>{{ form.prvni_cislo }}</td></tr> <tr><td>{{ form.operator.label }}: </td><td>{{ form.operator }}</td></tr> <tr><td>{{ form.druhe_cislo.label }}: </td><td>{{ form.druhe_cislo }}</td></tr> <tr><td></td><td><input type="submit" style="width: 100%;"></td></tr> </table> </form> {% for field, errors in form.errors.items() %} {% for error in errors %} <span style="color: red;">Chyba pole - {{ field }} hláška - {{ error }}</span><br> {% endfor %} {% endfor %} <hr> Výsledek: {% if vysledek %} {{ vysledek }} {% else %} Vyplň formulář {% endif %} {% endblock %}
Výsledok vyzerá nasledovne, všimnite si header a footer:
V budúcej lekcii, Static files a upload súborov vo Flask , sa pozrieme na statické súbory a nahrávanie.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 162x (1.75 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python