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í.

Lekce 4 - Kalkulačka v Django frameworku

V minulé lekci, Představení MVC a MVT architektury v Django, jsme si popsali MVT (MVC) architekturu.

V následujícím tutoriálu webových aplikací s frameworkem Django v Pythonu využijeme naše znalosti MVC architektury pro tvorbu základní jednoduché kalkulačky, která bude sčítat, odečítat, násobit a dělit. V dnešní lekci si MVC architekturu poprvé vyzkoušíme v praxi.

Kalkulačka v Django

Naše kalkulačka bude opravdu poměrně jednoduchá. Naučíme ji provádět pouze základní matematické operace:

  • sčítání,
  • odčítání,
  • násobení,
  • dělení.

Aplikace bude mít dvě vstupní políčka <input> pro čísla, jedno tlačítko <input type="submit"> pro odeslání formuláře a <select> na výběr operace s možnostmi +, -, * a /. V prohlížeči bude vypadat 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. Z předchozích lekcí již máme vytvořený projekt mysite, zadali jsme totiž příkaz:

django-admin 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áme, spustíme kód výše. Pokud máme, vypíše nám chybovou hlášku, že projekt již existuje.

Vytvoření aplikace

Přesuneme se do složky mysite/ a otevřeme příkazový řádek. 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:

py manage.py startapp calculator

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

Instalace aplikace

Postupujeme úplně stejně jako s naší první aplikací. Aplikaci je nyní třeba nainstalovat a proto v souboru/modulu (modul rovná se soubor, jelikož v Pythonu se každému souboru říká modul) \mysite\mysite\settings.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á views.

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:

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ěme si, že nyní do calculator.urls nenapojujeme kořenovou adresu projektu localhost:8000 jako u Ahoj světe, 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í musíme vytvořit routy aplikace odkazující na view, které bude URL adresu kalkulačky obsluhovat. Toto view vytvoříme později. Vytvořme tedy soubor mysite\calculator\urls.py a vložme do něj následující kód:

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 šablonu. Bude se nacházet v mysite\calculator\templates\calculator\kalkulacka.html. Vytvořme si tedy složku templates/, v ní podsložku calculator/ a v ní soubor kalkulacka.html. Vložme 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>

Dáme si pozor, aby byl soubor vytvořený v UTF-8 kódování! To platí pro všechny soubory, které budeme vytvářet.

CSRF útok

Pravděpodobně ná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. 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í.

Představme 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í. Tento zmíněný útok by byl ještě poměrně neškodný, ale co potom takový falešný formulář na odesílání peněz... Jaj :)

Vytvoření modelu

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 modelu. Představme 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. Do \mysite\calculator\models.py napíšeme následující kód:

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

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

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

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

Padly zde termíny "model" a "modul", ty nezaměňujme. 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 se po zadání URL adresy localhost:8000/calculator_aplikace 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 :)

Jak již víme, každá funkce view má povinný parametr request, kam se předá uživatelský požadavek. Náš view bude jistě využívat i 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. Ale to až za chvilku.

Nejdříve si v modulu \mysite\calculator\views.py vytvoříme funkci kalkulacka(), na kterou již odkazujeme ze souboru mysite\calculator\urls.py:

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 vůbec čí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 úmyslně pošle nějaký nesmysl. Formulář tedy nejprve zvalidujeme. Pokud nastane výjimka, vrátíme naši HTML šablonu 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 models

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 request.POST["operator"] == "/" and float(request.POST["b"]) == 0:
            error_msg = "Chyba dělení nulou"
            return render(request, "calculator/kalkulacka.html", dict(error_msg=error_msg, vysledek=vysledek))
        if request.POST["operator"] == "+":
            vysledek = models.secti(request.POST["a"], request.POST["b"])
        elif request.POST["operator"] == "-":
            vysledek = models.odecti(request.POST["a"], request.POST["b"])
        elif request.POST["operator"] == "/":
            vysledek = models.vydel(request.POST["a"], request.POST["b"])
        elif request.POST["operator"] == "*":
            vysledek = models.vynasob(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 zlepš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 nalezneme na adrese http://localhost:8000/calculator_aplikace/. Samozřejmě musíme 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:

Webová kalkulačka v Pythonu
localhost:8000/cal­culator_aplika­ce/

Zdrojové kódy jsou přiloženy na konci lekce.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

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

 

Předchozí článek
Představení MVC a MVT architektury v Django
Všechny články v sekci
Django - Tvorba webů v Pythonu
Přeskočit článek
(nedoporučujeme)
Kvíz - Základy frameworku Django
Článek pro vás napsal MQ .
Avatar
Uživatelské hodnocení:
102 hlasů
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity