IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

4. diel - Kalkulačka v Django frameworku

V minulej lekcii, Predstavenie MVC a MVT architektúry v Django , sme si popísali MVT (MVC) architektúru. Už vieme, že naše aplikácie v Django budú rozdelené na komponenty 3 typov:

  • Modely obsahujúce logiku ako Python kód
  • Templates obsahujúce šablóny ako HTML kód
  • Views, ktorá sa zavolajú podľa URL adresy a fungujú ako prostredník medzi modelmi a templates

V dnešnej lekcii si MVC architektúru prvýkrát vyskúšame, vytvoríme si totiž prvý plnohodnotnú webovú aplikáciu.

Kalkulačka

Bude sa jednať o jednoduchú kalkulačku, ktorá vykonáva nasledujúce matematické operácie:

  • súčet
  • rozdiel
  • súčin
  • podiel

Naša kalkulačka bude mať 2 vstupné políčka <input> na čísla, 1 tlačidlo <input type="submit"> na odoslanie formulára a <select> na výber operácie s možnosťami +, -, /, *. V prehliadači bude vyzerať asi takto:

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

Pusťme sa do toho.

Vytvorenie projektu

Webová aplikácia v podaní Django frameworku bude projekt s jednou aplikáciou s názvom "calculator". V druhej lekcii sme si už vytvorili projekt mysite a to príkazom:

py -m django startproject mysite

Už vieme, že projekt môže obsahovať viac aplikácií a tak môžeme kalkulačku pridať pokojne do tohto istého projektu. Pokiaľ tento projekt vytvorený nemáte, spustite kód vyššie. Ak áno, vypíše vám chybovú hlášku, že už existuje.

Vytvorenie aplikácie

Presunieme sa do priečinka C:\Users\<VaseJmeno>\AppData\Local\Programs\Python\ a pre zložku mysite otvoríme príkazový riadok. V ceste vyššie si samozrejme nahraďte <VaseJmeno> za názov vašej užívateľskej zložky. Ako zložku s Django projektmi otvoriť a ako v nej otvoriť príkazový riadok sme si podrobne ukazovali v lekcii Zoznámenie s Django frameworkom pre Python. V príkazovom riadku spustíme príkaz pre vytvorenie novej aplikácie calculator v tomto projekte:

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

Keďže po vykonaní príkazu sa nič nevypíše, môžete si jeho úspešnosť overiť tým, že sa pozriete, či sa v priečinku mysite vytvorila nová zložka calculator.

Inštalácia aplikácie

Postupujeme úplne rovnako ako vtedy s našou prvou aplikáciou. Aplikáciu je teraz potrebné nainštalovať a preto v súbore / module (ak napíšem modul, myslím tým súbor, pretože v Pythone sa každému súboru hovorí modul) /mysite/mysite/setting.py aplikáciu do zoznamu aplikácií pridáme:

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

Routovanie

Prejdime k routovanie, teda nadväzovanie URL adries na jednotlivé view.

Ruty projektu

Teraz je potrebné "importovať" všetky URL adresy z aplikácie do hlavného schémy URL adries, ktoré sa vždy nachádza v /nazev_projektu/nazev_projektu/urls.py, čo je u nás /mysite/mysite/urls.py. Ak pracujete s novým projektom, nezabudnite naimportovať funkciu 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šimnite si, že teraz do calculator.urls nenapojujeme koreňovú adresu projektu localhost:8000 ako u hello world, ale kalkulačka pobeží na adrese localhost:8000/calculator_aplikace. Jednotlivé aplikácie nášho projektu budeme teraz dávať do zložiek, aby sa všetky nehádali o jednu URL adresu.

Ruty aplikácie

Ruty projektu máme napojené na ruty aplikácie. Teraz ich musíme vytvoriť. Vytvorme teda súbor mysite\calculator\urls.py odkazujúce na view, ktorý bude URL adresu kalkulačky obsluhovať. Toto view vytvoríme neskôr.

from django.urls import path
from . import views

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

Šablóna

Pred tým, ako začneme písať logiku aplikácie, si vytvoríme template. Bude sa nachádzať v mysite/calculator/templates/calculator/kalkulacka.html. Vytvorte si teda zložku templates, v nej podpriečinok calculator a v nej súbor kalkulacka.html. Dajte si pozor, aby bol súbor vytvorený v UTF-8 kódovanie! To platí pre všetky súbory, ktoré budeme vytvárať. Vložte do neho nasledujúci 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

Pravdepodobne vás v kóde formulára zaujala direktíva {% csrf_token %}. V každom formulári Django vyžaduje tzv. CSRF "žetón", ktorý slúži proti útoku podvrhnuté formulára.

Predstavte si situáciu, kedy sme vytvorili nejaký populárny blog a niekto by vytvoril úplne inú stránku, kam by dal formulár nabádajúce na vkladanie vulgárnych príspevkov. Tento formulár by však nenechal odosielať dáta na jeho stránku, ale na view nášho blogu. Nič netušiaci užívatelia by razom písali príspevky na náš blog, aj keď by sa na tejto stránke vôbec nenachádzali a nevedeli, že tam niečo posielajú.

CSRF token opatrí formulár "žetónom", pomocou ktorého sa overuje, že bol odoslaný cez našu stránku a nie cez stránku cudzie. Tento spomínaný útok by bol ešte pomerne neškodný, skúste si predstaviť taký falošný formulár na odosielanie peňazí. jaj :)

Model

Teraz vytvoríme logiku aplikácie, teda funkcie, ktoré nám budú vracať výsledky. Takú logiku nikdy nepíšeme priamo do view, ale do modelov. Predstavte si, ako by inak vyzerali väčšie aplikácie, náš súbor s views by bol dlhý a neprehľadný. Toto rozdelenie sme si už vysvetľovali pri opise MVC architektúry v minulej lekcii. Vytvorte si modul /mysite/calculator/nas_modul.py s nasledujúcim obsahom.

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)

Padli tu termíny "model" a "modul", tie nezamieňajte. Model je súčasť MVC architektúry, modul je Python súbor. Každý náš model bude modulom, ale nie každý náš modul bude modelom :)

Vytvorenie view

Docielili sme toho, že po zadaní URL adresy localhost:8000/calculator_aplikace sa spustí view kalkulacka(). To je metóda v súbore views.py, kde užívateľský požiadavka obslúžime. Samozrejme k tomu použijeme model a template :)

Náš view bude určite využívať funkciu render(), pretože bude vracať HTML šablónu s formulárom. Ďalej prijme POST požiadavka, teda dáta odoslané týmto formulárom, vykoná vyžadovanú operáciu a vráti výsledok.

V module /mysite/calculator/views.py si vytvoríme funkciu kalkulacka(), na ktorú už odkazujeme zo súboru mysite\calculator\urls.py. Ako už vieme, každá funkcia view má povinný parameter request, kam sa odovzdá užívateľský požiadavku.

from django.shortcuts import render

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

Validácia

Ďalej potrebujeme zistiť, či boli vyplnené obe číslice, či sú to číslice, a či bol odoslaný operátor. V našich aplikáciách by sme mali predpokladať, že sa užívateľ môže pomýliť alebo že do nich schválne niekto pošle nejaký nezmysel. Formulár teda najprv zvaliduje. Ak nastane výnimka, vrátime náš HTML template s chybovým hlásením

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šetko je ošetrené.

Zostáva nám naimportovať náš model, odovzdať mu dáta a výsledok odovzdať šablóne. Presne toto je účelom 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 šablóny

Aby v šablóne zostávala vyplnená dáta a zobrazovala chybové hlášky, je potrebné v nej vypísať obsah error_msg, ktorú sme si vo view pripravili. Tiež aplikujeme vylepšováky, ktorý nám po odoslaní bude zobrazovať v input políčkach čísla, ktoré sme 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>

Spustenie

Kalkulačku nájdete na adrese http://localhost:8000/calculator_aplikace/. Samozrejme musíte prvýkrát spustiť server príkazom py manage.py runserver a to zo zložky so súborom manage.py, robili sme v minulých lekciách.

výsledok:

Tvoja stránka
localhost

Dúfam, že ste princíp MVC modelu pochopili a utvrdili svoje doterajšie znalosti Django frameworku. V budúcej lekcii, Databázy filmov v Django - Vytvorenie projektu a static files , začneme pracovať na väčšej aplikáciu, ktorá bude využívať aj databázu.


 

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é 292x (8.93 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python

 

Predchádzajúci článok
Predstavenie MVC a MVT architektúry v Django
Všetky články v sekcii
Tvorba webov v Django frameworku pre Python
Preskočiť článok
(neodporúčame)
Databázy filmov v Django - Vytvorenie projektu a static files
Článok pre vás napísal MQ .
Avatar
Užívateľské hodnotenie:
2 hlasov
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity