C/C++ week November Black Friday
Black Friday je tu! Využij jedinečnou příležitost a získej až 80 % znalostí navíc zdarma! Více zde
Pouze tento týden sleva až 80 % na e-learning týkající se C/C++

Lekce 2 - Seznámení s Flask microframeworkem

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Úvod do frameworku Flask a webových aplikací v Pythonu, jsme si vysvětlili jak fungují webové aplikace a proč jsou mnohem populárnější než ty desktopové. V dnešním Python tutoriálu se již budeme věnovat frameworku Flask.

Instalace

Pro instalaci potřebujeme Python3, já osobně používám Python3.6 Miniconda distribuci, ale Python již snad máte nainstalovaný. Nyní otevřeme příkazový řádek nebo Anaconda Prompt a spustíme následující příkaz, který nainstaluje Flask.

py -m pip install flask

Pokud používáte miniconda/anaconda, příkaz je jen pip install flask.

První aplikace - Hello World

Nejdříve si vytvoříme složku, kterou si můžete pojmenovat libovolně, a vytvoříme si v ní nový soubor main.py. Struktura složky bude vypadat následovně (složku, kterou jste si vytvořili, budu v článku nazývat root, což znamená anglicky kořen):

root/
    main.py

Jsme připraveni a můžeme si napsat naši první aplikaci ve Flasku, tou nebude nic jiného než Hello World :) Do souboru vložme:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World"

if __name__ == "__main__":
    app.run()

Nejprve si importujeme třídu Flask, poté vytvoříme instanci této třídy, což je aplikace podle standardu WSGI. Jako parametr konstruktoru tato třída požaduje název modulu, ve kterém se bude spouštět. Podle názvu modulu bude Flask hledat templaty a statické soubory. Poté vytvoříme funkci hello_world(), která vrací text "Hello World" a pomocí dekorátoru ji nastavíme adresu. Zkontrolujeme, zda se soubor spouští a není jen někam importován. Pokud se spouští, tak spustíme aplikaci.

Aplikaci spustíme příkazem py main.py z root/ složky a poté poběží na adrese http://127.0.0.1:5000/. Tu stačí nyní jen otevřít v prohlížeči:

127.0.0.1:5000
127.0.0.1:5000
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

To bylo jednoduché, že?

Druhá aplikace - Kalkulačka

Rovnou si vytvoříme i jednoduchou kalkulačku. Naučíme se pracovat s requesty a Jinja2 template enginem. Vytvořte si projekt v nové složce. V článku na ni budeme referovat opět jako na root/.

Kalkulačka bude provádět následující matematické operace:

  • součet
  • rozdíl
  • součin
  • podíl

Tentokrát toho budeme chtít po aplikaci vykreslit více, než pouhý text. Ještě před tím, než se vrhneme na samotný Flask, si musíme navrhnout šablonu, kterou umístíme do root/templates/kalkulacka.html. Kromě HTML kódu budeme v šabloně potřebovat vypsat výsledek, tedy proměnnou. V Jinja2 template enginu se proměnná vypíše jako {{ promenna }}.

Pokud bychom v šabloně chtěli vykonat nějaký příkaz, např. proměnné přiřadit hodnotu, vytvořit cyklus nebo podmínku, použijeme tento zápis: {% set hodnota = 5 %}, {% for i in pole %} {{ i }} {% endfor %}, {% if hodnota == 5 %} Hodnota je 5 {% endif %}. Ale nám dnes stačí výsledek pouze vypsat.

Obsah šablony bude následující:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <form method="GET">
        <input type="number" name="prvni_cislo">
        <input type="text" name="operator">
        <input type="number" name="druhe_cislo">
        <input type="submit">
    </form>
    <hr>
    Výsledek: {{ vysledek }}
</body>
</html>

Náš template bude vypadat v prohlížeči následovně:

127.0.0.1:5000
127.0.0.1:5000

Nyní přidáme logiku aplikace jako soubor main.py. Nejdříve si vezmeme hodnoty z requestu, požadavku odeslaném formulářem, a poté vrátíme template s výsledkem:

from flask import Flask, render_template, request

app = Flask(__name__)

def secti(a, b):
    return float(a) + float(b)

def odecti(a, b):
    return float(a) - float(b)

def podil(a, b):
    return float(a) / float(b)

def soucin(a, b):
    return float(a) * float(b)

@app.route("/", methods = ["GET", "POST"]) # Povolíme metody GET a POST
def kalkulacka():
    prvni_cislo = request.args.get("prvni_cislo") # Získáme hodnotu z GET requestu
    druhe_cislo = request.args.get("druhe_cislo")
    operator = request.args.get("operator")

    if prvni_cislo is None or druhe_cislo is None:
        return render_template("template.html", vysledek = "Vyplň formulář")
    if (float(druhe_cislo) == 0 and operator == "/"):
        vysledek = "Nelze dělit nulou"
        return render_template("template.html", vysledek = vysledek)
    if (operator == "+"):
        vysledek = secti(prvni_cislo, druhe_cislo)
    elif (operator == "-"):
        vysledek = odecti(prvni_cislo, druhe_cislo)
    elif (operator == "/"):
        vysledek = podil(prvni_cislo, druhe_cislo)
    elif (operator == "*"):
        vysledek = soucin(prvni_cislo, druhe_cislo)
    else:
        vysledek = "Chyba"

    return render_template("kalkulacka.html", vysledek = vysledek) # Vrátíme naší šablonu s výsledkem

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

Všimněte si, že ve funkci app.run() jsme nastavili parametr debug jako True. To znamená, že se nám budou vypisovat chyby. V reálné aplikaci nezapomeňte debug nastavit na False.

Hodnotu z requestu získáme následujícím způsobem:

  • Metoda GET
    • request.args["hodnota"] - Získáme hodnotu z GET requestu, tedy z parametrů URL adresy. Pokud neexistují, vyvolá error.
    • request.args.get("hodnota") - Získáme hodnotu z GET requestu, pokud neexistuje, vrací None. Pokud máme hodnotu víckrát, vrátí tu první.
    • request.args.getlist("hodnota") - Pokud pošleme hodnotu víckrát, vrátí nám list.
  • Metoda POST
    • Obdobné metody můžeme používat i pro metodu POST:
    • request.form["hodnota"]
    • request.form.get("hodnota")
    • request.form.getlist("hodnota")
  • Soubory
    • Pro přístup k nahraným souborům:
    • request.files["hodnota"]
    • request.files.get("hodnota")
    • request.files.getlist("hodnota")
  • GET + POST => preferuje GET:
    • A můžeme také přistupovat k jedné kolekci, která obsahuje jak GET, tak i POST parametry:
    • request.values["hodnota"]
    • request.values.get("hodnota")
    • request.values.getlist("hodnota")

Odesílání formuláře můžeme nyní provést metodou POST. V tomto případě již nebudou parametry následně viditelné v URL adrese, ale budou schované v těle požadavku. U formulářu se to tak dělá častěji:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <form method="POST">
        <input type="number" name="prvni_cislo">
        <input type="text" name="operator">
        <input type="number" name="druhe_cislo">
        <input type="submit">
    </form>
    <hr>
    Výsledek: {{ vysledek }}
</body>
</html>

V současné chvíli dostaneme následující error, jelikož metoda POST není povolena:

405 Method Not Allowed
127.0.0.1:5000

Metodu POST povolíme a parametry vytáhneme z request.form namísto z request.args:

from flask import Flask, render_template, request

app = Flask(__name__)

def secti(a, b):
    return float(a) + float(b)

def odecti(a, b):
    return float(a) - float(b)

def podil(a, b):
    return float(a) / float(b)

def soucin(a, b):
    return float(a) * float(b)

@app.route("/", methods = ["GET", "POST"]) # Povolíme metody GET a POST
def kalkulacka():
    prvni_cislo = request.form.get("prvni_cislo") #Získáme hodnotu z POST requestu
    druhe_cislo = request.form.get("druhe_cislo")
    operator = request.form.get("operator")
    if prvni_cislo is None or druhe_cislo is None:
        return render_template("template.html", vysledek = "Vyplň formulář")
    if (float(druhe_cislo) == 0 and operator == "/"):
        vysledek = "Nelze dělit nulou"
        return render_template("template.html", vysledek = vysledek)
    if (operator == "+"):
        vysledek = secti(prvni_cislo, druhe_cislo)
    elif (operator == "-"):
        vysledek = odecti(prvni_cislo, druhe_cislo)
    elif (operator == "/"):
        vysledek = podil(prvni_cislo, druhe_cislo)
    elif (operator == "*"):
        vysledek = soucin(prvni_cislo, druhe_cislo)
    else:
        vysledek = "Chyba"

    return render_template("kalkulacka.html", vysledek = vysledek) #Vrátíme naší šablonu s výsledkem

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

Máme hotovo, aplikace funguje stejně dobře jako předtím. V případě jakýchkoli problémů je máte pod článkem obě ke stažení. V příští lekci, WTForms a Jinja2 šablony pro Flask framework, kalkulačku zdokonalíme pomocí knihovny WTForms.


 

Stáhnout

Staženo 34x (2.32 kB)
Aplikace je včetně zdrojových kódů v jazyce Python

 

 

Aktivity (7)

 

 

Komentáře

Avatar
Jaroslav Porplycia:5.12.2018 13:17

Děkuji za tento seriál, přišel přesně ve chvíli, kdy jsem začal shánět informace o Flask.
V článku je jeden překlep - na začátku kalkulačky se píše vytvořit šablonu root/templates/kal­kulacka.html, ale dále se pracuje se šablonou template.html

 
Odpovědět
5.12.2018 13:17
Avatar
MQ .
Překladatel
Avatar
Odpovídá na Jaroslav Porplycia
MQ .:5.12.2018 13:39

Díky za upozornění :)

Editováno 5.12.2018 13:39
Odpovědět
5.12.2018 13:39
Programovácí jazyk zítřka bude vysokoúrovňový, bez ";", prostý a v neposlední řadě čitelný.
Avatar
JIrka Simon
Člen
Avatar
Odpovídá na MQ .
JIrka Simon:26.12.2018 20:33

Ahoj, taky diky za serial, na flask uz jsme se chvilku chystal.

Mimo preklep v template je jeste dalsi chybka, v sekci kdy pridame POST do template tak to nevyhodi zminovanou chybu, ale obe hodnoty vrati None (hodnota request.args.get je nevyplnena error by v main bylo pouze request.args[ABC]), protoze jsme si v prvni casti nadefinovali metodu POST v @app.route("/", methods = ["GET", "POST"]) . Zminovana chybka nastane ve chvili, kdy to z routy smazu. :-)
Jirka

 
Odpovědět
26.12.2018 20:33
Avatar
Jan Ledvina
Člen
Avatar
Jan Ledvina:9. dubna 17:39

nefunguje mi flask, může mi někdo dát číslo verze na verzi používanou při psaní tohoto článku prosím?

 
Odpovědět
9. dubna 17:39
Avatar
MQ .
Překladatel
Avatar
Odpovídá na Jan Ledvina
MQ .:10. dubna 21:09

Ahoj, tento článek byl psán pro nejnovější verzi (v té době, což není tak dávno), bylo by fajn, kdybys přiložil screen chybové hlášky, ať ti s tím můžeme pomoct :)

Odpovědět
10. dubna 21:09
Programovácí jazyk zítřka bude vysokoúrovňový, bez ";", prostý a v neposlední řadě čitelný.
Avatar
Jan Ledvina
Člen
Avatar
Jan Ledvina:14. dubna 20:45

toto je screen té chyby

 
Odpovědět
14. dubna 20:45
Avatar
MQ .
Překladatel
Avatar
Odpovídá na Jan Ledvina
MQ .:14. dubna 21:47

https://stackoverflow.com/…ation-fileno

Zkus použít přikazový řádek a ne IDLE shell.

Odpovědět
14. dubna 21:47
Programovácí jazyk zítřka bude vysokoúrovňový, bez ";", prostý a v neposlední řadě čitelný.
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Jan Ledvina
Člen
Avatar
Jan Ledvina:15. dubna 6:34

Okno příkazového řádku se otevře a hned zase zavře.

 
Odpovědět
15. dubna 6:34
Avatar
MQ .
Překladatel
Avatar
Odpovídá na Jan Ledvina
MQ .:15. dubna 20:56

Otevři si přikazový řádek ve win (https://www.wikihow.com/…t-in-Windows), dále se dostaň do složky se scriptem (použij příkaz "cd") a spusť ho příkazem "python muj_super_scrip­t.py" :)

Odpovědět
15. dubna 20:56
Programovácí jazyk zítřka bude vysokoúrovňový, bez ";", prostý a v neposlední řadě čitelný.
Avatar
Jan Ledvina
Člen
Avatar
Jan Ledvina:16. dubna 18:13

Ta samá chyba :-(.

 
Odpovědět
16. dubna 18:13
Avatar
MQ .
Překladatel
Avatar
Odpovídá na Jan Ledvina
MQ .:16. dubna 21:08

Tvé uživatelské jméno ve windows "C:/Users/Uži­vatel", způsobuje problém, jelikož obsahuje "ž". Přejmenuj tuto složku a ujisti se, zda nejsou v cestě, takto pojmenované složky a vše by mělo být ok :)

Odpovědět
16. dubna 21:08
Programovácí jazyk zítřka bude vysokoúrovňový, bez ";", prostý a v neposlední řadě čitelný.
Avatar
asifa.hvshthvg:29. června 21:17

Cau, v tom prvnim kodu te kalkulacky mas rovnou povoleny GET i POST takze ta chyba 405 Method Not Allowed se pak nevypise. Taky tam pracujes s template.html misto kalkulacka.html

 
Odpovědět
29. června 21:17
Avatar
Jan Ledvina
Člen
Avatar
Odpovídá na MQ .
Jan Ledvina:12. srpna 12:23

Dik za radu, už to funguje :-)

 
Odpovědět
12. srpna 12:23
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.