= Formuláre = Formuláre sú pre webovská aplikácie veľmi dôležité. V klasickom ponímaní je to jediný spôsob ako môžu užívatelia zaslať http serveru dáta. == Typické začiatočnícke chyby == Programovanie obsluhy formulárov je náchylné na chyby, napríklad: 1. Programátor predpokladá, že keď prídu dáta tak skutočne pochádzajú z formulára. Napríklad ak je vo formulári voľba muž/žena, kód pre spracovanie zaslaných dát predpokladá, že tam nemôže byť iný reťazec, napríklad marťan. 1. Programátor predpokladá, reťazce sú nanajvýš tak dlhé, ako vyžadoval vo formulári. Vedie k preťaženiu servra. 1. Programátor predpokladá, že zadané reťazce neobsahujú žiadne špeciálne znaky. Toto vedie k dvom typom chýb: a. [[http://en.wikipedia.org/wiki/SQL_injection | SQL injection.]] Vezmeme reťazec zadaný užívateľom a bez akejkoľvek kontroly z neho vyrobíme SQL reťazec, ktorý pošleme databázovému servru. Zlý užívateľ nám pošle napr. {{{ a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '%}}} a je zle. Toto je bohužiaľ ešte stále dosť rozšírená fatálna chyba webových aplikácií. a. [[http://en.wikipedia.org/wiki/Cross_Site_Scripting | Cross-site scripting.]] Vezmeme reťazec zadaný užívateľom a bez akejkoľvek kontroly ho zapíšeme do databázy a potom zobrazíme na stránke. Toto je veľmi časté. Problém je v tom, že tento reťazec môže obsahovať !JavaScript, ktorý môže so stránkou urobiť čokoľvek, napríklad zmeniť formulár pre zadávanie hesla tak, aby ho poslal nič netušiaci užívateľ útočníkovi. Bod 3a sa rieši v djangu tým, že používame modely. Bod 3b je vyriešený, ak dôsledne používame šablóny -- t.j. žiadne explicitné HTML vo views. Template.render totiž všetko HTML ktoré prípadne obsahuje Context prerobí na neškodný plochý text. Ochranu pred chybami spomenutými v bodoch 1. a 2. pre nás django zabezpečuje prostredníctvom triedy {{{Form}}} == Trieda Form == Formuláre v djangu vyžívajú sebareflexívne vlastnosti Pythonu. === Neviazané formuláre === {{{#!python $ ./manage.py shell Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26) [GCC 4.3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from django import forms >>> class MyForm(forms.Form): ... meno=forms.CharField(max_length=20) ... priezvisko=forms.CharField(max_length=20,required=True) ... znamka=forms.IntegerField(min_value=1,max_value=5,required=True) ... protekcny_ziak=forms.BooleanField() ... >>> form=MyForm() }}} Vytvorili sme neviazanú inštanciu triedy {{{Form}}}. Trieda {{{Form}}} implementuje metódu {{{__repr__}}}: {{{ >>> print form }}} to znamená, že v šablóne môžeme použiť {{{ {{ form }} }}}. V browseri to potom vyzerá takto: {{{#!html
}}} Všimnite si, že tam nie je odosielací button; ten patrí do šablóny. Vykresľovať formulár ako tabuľku nie je jediná možnosť: {{{#!python >>> print form.as_ul()
  • }}} vyzerá takto: {{{#!html }}} alebo {{{#!python >>> print form.as_p()

    }}} vyzerá takto {{{#!html

    }}} Ak sa to niekomu nepáči, môže pokojne použiť CSS aby si veci zafarbil podľa svojho gusta. === Viazané formuláre === Viazaný formulár vznikne tak, že sa skonštruuje zo slovníka zobrazujúceho reťazce na reťazce. V praxi sú to užívateľom zaslané dáta. {{{#!python >>> form=MyForm({'meno':'Jozef','priezvisko':'Mak','znamka':'3','protekcny_ziak':'1'}) }}} Jednoduchým spôsobom môžeme skontrolovať, či sú dáta v poriadku. {{{#!python >>> print form.is_valid() True }}} Vo form.cleaned_data máme teraz k dispozícii slovník s dátami. {{{#!python >>> print form.cleaned_data {'znamka': 3, 'meno': u'Jozef', 'priezvisko': u'Mak', 'protekcny_ziak': True} }}} Všimnite si, že dáta už sú správneho typu: {{{#!python >>> for key in form.cleaned_data: ... print "typ hodnoty",key,"is",type(form.cleaned_data[key]).__name__ ... typ hodnoty znamka is int typ hodnoty meno is unicode typ hodnoty priezvisko is unicode typ hodnoty protekcny_ziak is bool }}} Teraz vyskúšame, čo urobia chybné dáta. Ako {{{znamka}}} pošleme nečíslo. {{{#!python >>> form=MyForm({'meno':'Jozef','priezvisko':'Mak','znamka':'xxx','protekcny_ziak':'1'}) >>> print form.is_valid() False }}} To sa dalo čakať. Čo ale teraz? Mali by sme byť schopní zistiť, aká je chyba v zaslaných dátach a požadovať od užívateľa nápravu. Django to ale zabezpečí za nás: {{{#!python >>> print form >>> }}} Vyzerá takto: {{{#!html
    • Enter a whole number.
    }}} * Užívateľom zaslané dáta sú predvyplnené. * Django zahlásil chybu v angličine, lokalizovať chybové hlášky do iného jazyka je možné pomocou nastavenia v {{{settings.py}}}. * V HTML vidno, že zoznam chýb má triedu {{{errorlist}}}. V CSS môžeme tejto triede nastaviť atribúty podľa ľubovôle. * V praxi nás nemusí zaujímať, aká je chyba vo formulári. Stačí sa pozrieť na {{{form.is_valid()}}} a ak nevráti {{{True}}}, zobraziť formulár znovu. Skúsme ešte narobiť trchu viac a iných chýb: {{{#!python >>> form=MyForm({'meno':'Jozefxxxxxxxxxxxxxxxxxxxxxxxxxxxx','znamka':'10','protekcny_ziak':'1'}) >>> print form.is_valid() False >>> print form }}} {{{#!html
    • Ensure this value has at most 20 characters (it has 33).
    • This field is required.
    • Ensure this value is less than or equal to 5.
    }}}