Chci geek triko! Chci geek triko!
Extra 10 % bodů navíc a tričko zdarma při zadání kódu "TRIKO10"

Lekce 4 - Kalkulačka v Django frameworku

Python Django Kalkulačka v Django frameworku

Unicorn College ONEbit hosting 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, Představení MVC a MVT architektury v Django, jsme si popsali MVT (MVC) architekturu. Již víme, že naše aplikace v Django budou rozdělené na komponenty 3 typů:

  • Modely obsahující logiku jako Python kód
  • Templates obsahující šablony jako HTML kód
  • Views, která se zavolají podle URL adresy a fungují jako prostředník mezi modely a templates

V dnešní lekci si MVC architekturu poprvé vyzkoušíme, vytvoříme si totiž první plnohodnotnou webovou aplikaci.

Kalkulačka

Bude se jednat o jednoduchou kalkulačku, která provádějící následující matematické operace:

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

Naše kalkulačka bude mít 2 vstupní políčka <input> na čísla, 1 tlačítko <input type="submit"> na odeslání formuláře a <select> na výběr operace s možnostmi +, -, /, *. V prohlížeči bude vypadat asi takto:

Webová kalkulačka v Pythonu
http://localhos­t:8000/calcula­tor_aplikace/

Pusťme se do toho.

Vytvoření projektu

Webová aplikace v podání Django frameworku bude projekt s jednou aplikací s názvem "calculator". V druhé lekci jsme si již vytvořili projekt mysite a to příkazem:

py -m django startproject mysite

Již víme, že projekt může obsahovat více aplikací a tak můžeme kalkulačku přidat klidně do tohoto stejného projektu. Pokud tento projekt vytvořený nemáte, spusťte kód výše. Pokud ano, vypíše vám chybovou hlášku, že již existuje.

Vytvoření aplikace

Přesuneme se do složky C:\Users\<VaseJmeno>\AppData\Local\Programs\Python\ a pro složku mysite otevřeme příkazový řádek. V cestě výše si samozřejmě nahraďte <VaseJmeno> za název vaší uživatelské složky. Jak složku s Django projekty otevřít a jak v ní otevřít příkazový řádek jsme si podrobně ukazovali v lekci Seznámení s Django frameworkem pro Python. V příkazovém řádku spustíme příkaz pro vytvoření nové aplikace calculator v tomto projektu:

C:\Users\<VaseJmeno>\AppData\Local\Programs\Python\>py manage.py startapp calculator

Jelikož po provedení příkazu se nic nevypíše, můžete si jeho úspěšnost ověřit tím, že se podíváte, zda se ve složce mysite vytvořila nová složka calculator.

Instalace aplikace

Postupujeme úplně stejně jako tenkrát s naší první aplikací. Aplikaci je nyní třeba nainstalovat a proto v souboru/modulu (pokud napíši modul, myslím tím soubor, jelikož v Pythonu se každému souboru říká modul) /mysite/mysite/setting.py aplikaci do seznamu aplikací přidáme:

INSTALLED_APPS = [
    'calculator',
    'ahoj_svete',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Routování

Přejděme k routování, tedy navazování URL adres na jednotlivá view.

Routy projektu

Nyní je třeba "importovat" všechny URL adresy z aplikace do hlavního schématu URL adres, které se vždy nachází v /nazev_projektu/nazev_projektu/urls.py, což je u nás /mysite/mysite/urls.py. Pokud pracujete s novým projektem, nezapomeňte naimportovat funkci include() z modulu django.urls.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
        path('', include("ahoj_svete.urls")),
        path("calculator_aplikace/", include("calculator.urls")),
]

Všimněte si, že nyní do calculator.urls nenapojujeme kořenovou adresu projektu localhost:8000 jako u hello world, ale kalkulačka poběží na adrese localhost:8000/calculator_aplikace. Jednotlivé aplikace našeho projektu budeme nyní dávat do složek, aby se všechny nehádaly o jednu URL adresu.

Routy aplikace

Routy projektu máme napojené na routy aplikace. Nyní je musíme vytvořit. Vytvořme tedy soubor mysite\calculator\urls.py odkazující na view, který bude URL adresu kalkulačky obsluhovat. Toto view vytvoříme později.

from django.urls import path
from . import views

urlpatterns = [
    path("", views.kalkulacka, name="kalkulacka"),
]

Šablona

Před tím, než začneme psát logiku aplikace, si vytvoříme template. Bude se nacházet v mysite/calculator/templates/calculator/kalkulacka.html. Vytvořte si tedy složku templates, v ní podsložku calculator a v ní soubor kalkulacka.html. Dejte si pozor, aby byl soubor vytvořený v UTF-8 kódování! To platí pro všechny soubory, které budeme vytvářet. Vložte do něj následující obsah:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Webová kalkulačka v Pythonu</title>
</head>
<body>
    <form method="POST">
        {% csrf_token %}
        <input type="text" name="a">
        <select name="operator">
            <option value="+">+</option>
            <option value="-">-</option>
            <option value="*">*</option>
            <option value="/">/</option>
        </select>
        <input type="text"><br>
        <input type="submit">
    </form>
</body>
</html>

CSRF útok

Pravděpodobně vás v kódu formuláře zaujala direktiva {% csrf_token %}. V každém formuláři Django vyžaduje tzv. CSRF "žeton", který slouží proti útoku podvržení formuláře.

Představte si situaci, kdy jsme vytvořili nějaký populární blog a někdo by vytvořil úplně jinou stránku, kam by dal formulář vybízející ke vkládání vulgárních příspěvků. Tento formulář by ovšem nenechal odesílat data na jeho stránku, ale na view našeho blogu. Nic netušící uživatelé by rázem psali příspěvky na náš blog, i když by se na této stránce vůbec nenacházeli a nevěděli, že tam něco posílají.

CSRF token opatří formulář "žetonem", pomocí kterého se ověřuje, že byl odeslán přes naší stránku a ne přes stránku cizí. Tento zmíněný útok by byl ještě poměrně neškodný, zkuste si představit takový falešný formulář na odesílání peněz. Jaj :)

Model

Nyní vytvoříme logiku aplikace, tedy funkce, které nám budou vracet výsledky. Takovou logiku nikdy nepíšeme přímo do view, ale do modelů. Představte si, jak by jinak vypadaly větší aplikace, náš soubor s views by byl dlouhý a nepřehledný. Toto rozdělení jsme si již vysvětlovali při popisu MVC architektury v minulé lekci. Vytvořte si modul /mysite/calculator/nas_modul.py s následujícím obsahem.

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)

Padly zde termíny "model" a "modul", ty nezaměňujte. Model je součást MVC architektury, modul je Python soubor. Každý náš model bude modulem, ale ne každý náš modul bude modelem :)

Vytvoření view

Docílili jsme toho, že po zadání URL adresy localhost:8000/calculator_aplikace se spustí view kalkulacka(). To je metoda v souboru views.py, kde uživatelský požadavek obsloužíme. Samozřejmě k tomu použijeme model a template :)

Náš view bude určitě využívat funkci render(), jelikož bude vracet HTML šablonu s formulářem. Dále přijme POST požadavek, tedy data odeslaná tímto formulářem, provede vyžadovanou operaci a vrátí výsledek.

V modulu /mysite/calculator/views.py si vytvoříme funkci kalkulacka(), na kterou již odkazujeme ze souboru mysite\calculator\urls.py. Jak již víme, každá funkce view má povinný parametr request, kam se předá uživatelský požadavek.

from django.shortcuts import render

def kalkulacka(request):
    error_msg = None
    vysledek = None

Validace

Dále potřebujeme zjistit, zda byly vyplněny obě číslice, zda jsou to číslice, a zda byl odeslán operátor. V našich aplikacích bychom měli předpokládat, že se uživatel může splést nebo že do nich schválně někdo pošle nějaký nesmysl. Formulář tedy nejprve zvalidujeme. Pokud nastane výjimka, vrátíme náš HTML template s chybovou hláškou

from django.shortcuts import render

def kalkulacka(request):
    error_msg = None
    vysledek = None
    if request.method == "POST":
            try:
                float(request.POST["a"])
                float(request.POST["b"])
            except:
                error_msg = "A nebo B není číslo!"
                return render(request, "calculator/kalkulacka.html", dict(error_msg=error_msg, vysledek=vysledek))

Vše je ošetřeno.

Zbýva nám naimportovat náš model, předat mu data a výsledek předat šabloně. Přesně toto je účelem view:

from django.shortcuts import render

from . import nas_modul

def kalkulacka(request):
    error_msg = None
    vysledek = None
    if request.method == "POST":
            try:
                float(request.POST["a"])
                float(request.POST["b"])
            except:
                error_msg = "A nebo B není číslo!"
                return render(request, "calculator/kalkulacka.html", dict(error_msg=error_msg, vysledek=vysledek))

            if (float(request.POST["b"]) == 0 and request.POST["operator"] == "/"):
                    error_msg = "Chyba dělení nulou"
                    return render(request, "calculator/kalkulacka.html", dict(error_msg=error_msg, vysledek=vysledek))
            if (request.POST["operator"] == "+"):
                vysledek = nas_modul.secti(request.POST["a"], request.POST["b"])
            elif (request.POST["operator"] == "-"):
                vysledek = nas_modul.odecti(request.POST["a"], request.POST["b"])
            elif (request.POST["operator"] == "/"):
                vysledek = nas_modul.podil(request.POST["a"], request.POST["b"])
            elif (request.POST["operator"] == "*"):
                vysledek = nas_modul.soucin(request.POST["a"], request.POST["b"])
            else:
                error_msg = "Něco se pokazilo :("
                return render(request, "calculator/kalkulacka.html", dict(error_msg=error_msg, vysledek=vysledek))
    return render(request, "calculator/kalkulacka.html", dict(error_msg=error_msg, vysledek=vysledek))

Úprava šablony

Aby v šabloně zůstávala vyplněná data a zobrazovala chybové hlášky, je třeba v ní vypsat obsah error_msg, kterou jsme si ve view připravili. Také aplikujeme vylepšovák, který nám po odeslání bude zobrazovat v input políčkách čísla, která jsme zadali, a ponechá vybraný operátor.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
        <title>Webová kalkulačka v Pythonu</title>
</head>
<body>
    <form method="POST">
        {% csrf_token %}
        <span style="color: red;">{{error_msg}}</span>
        <br>
        <input type="text" name="a" value={{request.POST.a}}>
        <select name="operator">
            <option value="+" {% if request.POST.operator == "+" %} selected {% endif %}>+</option>
            <option value="-" {% if request.POST.operator == "-" %} selected {% endif %}>-</option>
            <option value="*" {% if request.POST.operator == "*" %} selected {% endif %}>*</option>
            <option value="/" {% if request.POST.operator == "/" %} selected {% endif %}>/</option>
        </select>
        <input type="text" name="b" value={{request.POST.b}}><br>
        <input type="submit"><br>
        {{vysledek}}
    </form>
</body>
</html>

Spuštění

Kalkulačku naleznete na adrese http://localhost:8000/calculator_aplikace/. Samozřejmě musíte prvně spustit server příkazem py manage.py runserver a to ze složky se souborem manage.py, dělali jsme v minulých lekcích.

Výsledek:

Your page
localhost

Doufám, že jste princip MVC modelu pochopili a utvrdili své dosavadní znalosti Django frameworku. V příští lekci, Databáze filmů v Django - Vytvoření projektu a static files, začneme pracovat na větší aplikaci, která bude využívat i databázi.


 

Stáhnout

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

 

 

Článek pro vás napsal MQ .
Avatar
Jak se ti líbí článek?
2 hlasů
Autor je srdcem Pythonista.
Aktivity (4)

 

 

Komentáře

Avatar
Stanislav Hrabovský:14. května 11:40

Jsem velice rád, že tu někdo dělá Django. Těším se na další díl... DĚKUJI!

 
Odpovědět  +1 14. května 11:40
Avatar
czech.freak
Člen
Avatar
czech.freak:18. srpna 10:51

Autor to sice uvádí s vykřičníkem, ale na základě mých zkušeností to ještě zopakuji: ukládejte v UTF-8 a bacha na editor PSPad, který i po zvolení Formát>UTF-8 ukládá (občas) s kódováním produkujícím chybu.
Při uložení editorem Sublime Text 3 vše OK.

 
Odpovědět 18. srpna 10:51
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 2 zpráv z 2.