IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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:

Chybová hláška pri validáciu formulárov vo WTForms vo Flask frameworku v Pythone - Flask framework pre Python

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:

Flask framework pre Python

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

 

Predchádzajúci článok
Zoznámenie s Flask microframeworkem
Všetky články v sekcii
Flask framework pre Python
Preskočiť článok
(neodporúčame)
Static files a upload súborov vo Flask
Článok pre vás napísal MQ .
Avatar
Užívateľské hodnotenie:
1 hlasov
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity