Projekt s formulármi
Projekt má za úlohy vykonávať základné operácie podľa formulára.
Začnime šablónou pre formulár:
{% extends "base.html" %} {% block nadpis %} Formulár {% endblock %} {% block obsah %} <form action="/form/" method="POST"> <table id="border"> {{ form.as_table }} </table> <input type="submit" value="Odošli" /> </form> {% endblock %}form.txt
Tagy <form> a <table> sú v šablóne.
<form> obsahuje URL, ktoré preberá dáta; toto URL je teraz rovnaké ako to, ktoré vykresľuje formulár
- Tag pre odosielací button je tiež v šablóne
views.py obsahuje jedinú funkciu:
1 # -*- coding: utf-8 -*-
2 from django import forms
3 from django.shortcuts import render_to_response
4
5 class MathOpForm(forms.Form):
6 operand1=forms.IntegerField(required=True)
7 operand2=forms.IntegerField(required=True)
8 operation=forms.ChoiceField(choices=[('+','+'),('-','-'),('*','*')],required=True)
9
10
11 __oper_map={'+':'__add__','-':'__sub__','*':'__mul__'}
12
13 def math_form(request):
14
15 global __oper_map
16
17 if request.method=='POST':
18 form=MathOpForm(request.POST)
19 # form.is_valid() skontroluje,
20 # ci su udaje vo formulari v poriadku
21 if form.is_valid():
22 # Vzhladom na to, ze form.is_valid() je True,
23 # mozeme tu uz predpokladat, ze data su v poriadku.
24
25 # slovnik cleaned_data uz obsahuje *cisla* ako operandy
26 operand1=form.cleaned_data['operand1']
27 operand2=form.cleaned_data['operand2']
28 # operation je retazec
29 operation=form.cleaned_data['operation']
30
31 # Trochu pythonovskeho voodoo:
32 # * operation je jedna z '+','-','*'
33 # * __oper_map je globalna premenna tohto modulu typu slovnik (vid hore)
34 # * __oper_map['+'] je napr. retazec '__add__'
35 # * operand1 je typu int
36 # * getattr(operand1,'__add__') vrati viazanu metodu z namespace
37 # toho objektu typu int
38 # * tejto metode je poslany operand2_int
39 #
40 # Skuste si na pythonovskom prompte:
41 # 1.__add__
42 # 1.__add__(2)
43 # getattr(1,'__add__')
44 # getattr(1,'__add__')(2)
45 if not (operation in __oper_map):
46 # Sem sa nikdy nedostaneme, to zabezpeci .is_valid
47 # Ale istota je istota
48 return(render_to_response("chyba.html",
49 {'chyba':u"Neznáma operácia"}))
50 vysledok=getattr(operand1,__oper_map[operation])(operand2)
51 return(render_to_response("vysledok.html",
52 {'operand1':operand1,
53 'operand2':operand2,
54 'operation':operation,
55 'vysledok':vysledok}))
56 else:
57 form=MathOpForm()
58 # Sem sa dostaneme v dvoch pripadoch
59 # 1) request.method nie je 'POST', teda je to takmer iste 'GET'
60 # v tom pripade sa vykonalo form=MathOpForm(), a teda formular
61 # je prazdny.
62 # 2) form.is_valid() vratilo False, v tom pripade je form zkonstruovany
63 # z POST requestu s vyznacenymi chybami.
64 return(render_to_response("form.html",{'form':form}))
nemusíme sa explicitne starať o to, či užívateľ zaslal správne dáta. Staci otestovat form.is_valid().
Django zabezpečí, že vo form.cleaned_data máme v operandoch už rovno čísla. V projekte násobky a delitele sme sa museli starať o prevod string->int, tu sa nemusíme.
- Dokonca aj kontrola, ci je operácia jeden z povolených znakov je zbytočná a nemusela by tam byť. Je tam iba pre istotu.
Celý projekt máte tu: forms_v1.1.1.tar.gz.
Vyskúšajte si attack.html, nech vidíte ako django reaguje na nelegálne dáta.