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.
V nasledujúcom tutoriáli webových aplikácií s frameworkom Django v Pythone využijeme naše znalosti MVC architektúry pre tvorbu základnej jednoduchej kalkulačky, ktorá bude sčítať, odčítať, násobiť a deliť. V dnešnej lekcii si MVC architektúru po prvýkrát vyskúšame v praxi.
Kalkulačka v Django
Naša kalkulačka bude skutočne pomerne jednoduchá. Naučíme ju vykonávať iba základné matematické operácie:
- sčítanie,
- odčítanie,
- násobenie,
- delenie.
<input>
pre
čísla, jedno tlačidlo <input type="submit">
pre odoslanie
formulára a <select>
na výber operácie s možnosťami
+
, -
, *
a /
. V prehliadači
bude vyzerať takto:
Pusťme sa do toho.
Vytvorenie projektu
Webová aplikácia v podaní Django frameworku bude projekt s jednou
aplikáciou s názvom calculator
. Z predchádzajúcich lekcií už
máme vytvorený projekt mysite
, zadali sme totiž príkaz:
django-admin startproject mysite
Už vieme, že projekt môže obsahovať viacero aplikácií, a tak môžeme kalkulačku pridať pokojne do tohto rovnakého projektu. Pokiaľ tento projekt vytvorený nemáme, spustíme kód vyššie. Ak máme, vypíše nám chybovú hlášku, že projekt už existuje.
Vytvorenie aplikácie
Presunieme sa do zložky mysite/
a otvoríme príkazový riadok.
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 na
vytvorenie novej aplikácie calculator
v tomto projekte:
py manage.py startapp calculator
Keďže sa po vykonaní príkazu nič nevypíše, môžeme si jeho
úspešnosť overiť tým, že sa pozrieme, či sa v zložke
mysite/
vytvorila nová zložka calculator/
.
Inštalácia aplikácie
Postupujeme úplne rovnako ako s našou prvou aplikáciou. Aplikáciu je
teraz potrebné nainštalovať a preto v súbore/module (modul rovná sa
súboru, pretože v Pythone sa každému súboru hovorí modul)
\mysite\mysite\settings.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 routovaniu, teda nadväzovaniu URL adries na jednotlivé views.
Teraz je potrebné importovať všetky URL adresy z aplikácie do hlavnej
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
:
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šimnime si, že teraz do calculator.urls
nenapájame koreňovú adresu projektu localhost:8000
ako u
Ahoj světe
, 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.
Routy aplikácie
Routy projektu máme napojené na routy aplikácie. Teraz musíme vytvoriť
routy aplikácie odkazujúce na view, ktoré bude URL adresu kalkulačky
obsluhovať. Toto view vytvoríme neskôr. Vytvorme teda súbor
mysite\calculator\urls.py
a vložme do neho nasledujúci kód:
from django.urls import path from . import views urlpatterns = [ path("", views.kalkulacka, name="kalkulacka"), ]
Šablóna
Pred tým, než začneme písať logiku aplikácie, si vytvoríme šablónu.
Bude sa nachádzať v
mysite\calculator\templates\calculator\kalkulacka.html
. Vytvorme si
teda zložku templates/
, v nej podzložku calculator/
av nej súbor kalkulacka.html
. Vložme 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>
Dáme si pozor, aby bol súbor vytvorený v UTF-8 kódovaní! To platí pre všetky súbory, ktoré budeme vytvárať.
CSRF útok
Pravdepodobne ná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 podvrhnutia
formulára. 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 cudziu.
Predstavme 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úci 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 použí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ú. Tento spomínaný útok by bol ešte pomerne neškodný, ale čo potom taký falošný formulár na odosielanie peňazí... Jaj
Vytvorenie modelu
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 modelu.
Predstavme 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. Do \mysite\calculator\models.py
napíšeme
nasledujúci 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)
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 to, že sa po zadaní URL adresy
localhost:8000/calculator_aplikace
spustí view
kalkulacka()
. To je metóda v súbore views.py
, kde
užívateľskú požiadavku obslúžime. Samozrejme na to použijeme
model a template
Ako už vieme, každá funkcia view má povinný parameter
request
, kam sa odovzdá užívateľská požiadavka. Náš view
bude určite využívať aj 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. Ale to až za chvíľku.
Najskôr si v module \mysite\calculator\views.py
vytvoríme
funkciu kalkulacka()
, na ktorú už odkazujeme zo súboru
mysite\calculator\urls.py
:
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 vôbec čí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 úmyselne pošle nejaký nezmysel. Formulár teda najskôr zvalidujeme. Pokiaľ nastane výnimka, vrátime našu HTML šablónu 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š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 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 šablóny
Aby v šablóne zostávali vyplnené dáta a zobrazovali chybové hlášky,
treba v nej vypísať obsah error_msg
, ktorú sme si vo view
pripravili. Tiež aplikujeme zlepšovák, 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ájdeme na adrese
http://localhost:8000/calculator_aplikace/
. Samozrejme musíme
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:
Zdrojové kódy sú priložené na konci lekcie.
V nasledujúcom kvíze, Kvíz - Základy frameworku Django, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
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é 329x (8.93 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python