RkBlog

Hardware, programming and astronomy tutorials and reviews.

Formularze w Django

W pliku z widokami importujemy formularze za pomoc膮:
from django import forms
Biblioteka sk艂ada si臋 z 3 komponent贸w:
  • Widget - klasa odpowiadaj膮ca za kod HTML.
  • Field - klasa odpowiedzialna za walidacj臋, np. pole EmailField sprawdza czy podana warto艣膰 jest poprawnym adresem email.
  • Form - zbi贸r p贸l, kt贸re wiedz膮 jak si臋 walidowa膰 i jak si臋 wy艣wietla膰 jak HTML.

Obiekty Form

Podstawow膮 czynno艣ci膮 b臋dzie tworzenie obiekt贸w Form, poprzez dziedziczenie django.forms.Form i podanie zbioru p贸l, o to przyk艂ad:
class TestForm(forms.Form):
	subject = forms.CharField(max_length=100)
	message = forms.CharField()
	sender = forms.EmailField()
W celu otrzymania kodu HTML formularza wystarczy utworzy膰 obiekt:
f = TestForm()
print f
Wynik:
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
Zwr贸膰 uwag臋 偶e nie ma tag贸w TABLE oraz FORM - ty musisz je doda膰 w szablonie. Mo偶na r贸wnie偶 otrzyma膰 formularz w postaci listy LI za pomoc膮 metody as_ul() oraz z wykorzystaniem taga P za pomoc膮 as_p().
Przyk艂adowy widok:
def testform(request):
	f = TestForm()
	return render_to_response('content/test.html', {'f1': f, 'f2': f.as_ul(), 'f3': f.as_p()})
Kod szablonu:
<table>
{{ f1 }}
</table>

<br /><hr /><br />

<ul>
{{ f2 }}
</ul>

<br /><hr /><br />

{{ f3 }}
Mo偶na poda膰 te偶 pocz膮tkowe warto艣ci do formularza, wystarczy umie艣ci膰 je w s艂owniku podanym jako pierwszy argument obiektu formularza:
class TestForm(forms.Form):
	subject = forms.CharField(max_length=100)
	message = forms.CharField()
	sender = forms.EmailField()

def test_view(request):
	a = TestForm({'subject':'temat', 'message':'wiadomo艣膰', 'sender': '1@1.pl'})
	return render_to_response('test.html', {'a':a}, context_instance=RequestContext(request))
Je偶eli nie podany dany dla wszystkich wymaganych p贸l to wy艣wietl膮 si臋 uwagi i偶 dane pole jest wymagane. Poprawno艣膰 wprowadzonych mo偶emy sprawdzi膰 za pomoc膮 metody is_valid() zwracaj膮cej True/False, a komunikaty wy艣wietli膰 za pomoc膮 metody errors() zwracaj膮cej s艂ownik o kluczach takich jak nazwy p贸l. Atrybut cleaned_data zwr贸ci s艂ownik ze "znormalizowanymi" danymi. Przyk艂adowo wprowadzona data w postaci 艂a艅cucha stanie si臋 obiektem datetime.date. Atrybut ten istnieje tylko gdy formularz ma poprawne dane (nale偶y wywo艂a膰 najpierw is_valid()).
def test_view(request):
	a = TestForm({'subject':'temat', 'message':'wiadomo艣膰', 'sender': '1@1.pl'})
	print a.is_valid()
	print a.cleaned_data
	return render_to_response('test.html', {'a':a}, context_instance=RequestContext(request))
True
{'message': u'wiadomo艣膰', 'sender': u'1@1.pl', 'subject': u'temat'}
By uzyska膰 dost臋p do samych p贸l formularza wystarczy odwo艂ywa膰 si臋 do p贸l stosuj膮c sk艂adni臋 s艂ownika i nazwy p贸l jako klucze, np:
def test_view(request):
	a = TestForm({'subject':'temat', 'message':'wiadomo艣膰', 'sender': '1@1.pl'})
	print a['sender']
	return render_to_response('test.html', {'a':a}, context_instance=RequestContext(request))

Obs艂uga formularzy w widokach

Poni偶ej zaprezentowano przyk艂adowy widok obs艂uguj膮cy formularz i jego walidacj臋:
def test_view(request):
	if request.method == 'POST':
		# dane z POST
		form = TestForm(request.POST)
		if form.is_valid():
			print 'ok'
			# dane poprawne
			return HttpResponseRedirect('/a/')
		else:
			# dane niepoprawne
			return render_to_response('test.html', {'a':form}, context_instance=RequestContext(request))
	else:
		# formularz
		a = TestForm()
		return render_to_response('test.html', {'a':a}, context_instance=RequestContext(request))

Pola formularzy

Ka偶de pole formularza po偶na konfigurowa膰 za pomoc膮 parametr贸w:
  • required - domy艣lnie True, oznacza i偶 pole jest wymagane
  • label - mo偶emy poda膰 etykiet臋 pola, czyli tekst jaki pojawi si臋 obok pola
  • initial - pozwala okre艣li膰 pocz膮tkow膮 warto艣膰
  • widget - pozwala okre艣li膰 widget jaki ma zosta膰 u偶yty do wy艣wietlenie pola
  • help_text - dodatkowy tekst pomocy
Dost臋pnych jest szereg typ贸w p贸l:
  • BooleanField - Pole checkbox na warto艣ci True/False
  • CharField - pole text, dodatkowe argument to max_length i min_length okre艣laj膮ce maksymaln膮 i minimaln膮 d艂ugo艣膰 wprowadzonego tekstu
  • ChoiceField - pole select przyjmuj膮ce argument choices - list臋 lub tupl臋 z艂o偶on膮 z 2 elementowych tupli.
  • DateField - pole text walidowane jako data. Argument input_formats umo偶liwia okre艣lenie dopuszczalnych format贸w, domy艣lnie akceptuje:
    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
    '%b %d %Y', '%b %d, %Y',            # 'Oct 25 2006', 'Oct 25, 2006'
    '%d %b %Y', '%d %b, %Y',            # '25 Oct 2006', '25 Oct, 2006'
    '%B %d %Y', '%B %d, %Y',            # 'October 25 2006', 'October 25, 2006'
    '%d %B %Y', '%d %B, %Y',            # '25 October 2006', '25 October, 2006'
    
  • DateTimeField - pole text walidowane jako data i czas. Domy艣lnie akceptuje formaty:
    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
    '%Y-%m-%d',              # '2006-10-25'
    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
    '%m/%d/%Y',              # '10/25/2006'
    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
    '%m/%d/%y',              # '10/25/06'
  • DecimalField - pole text na liczby zmiennoprzecinkowe. Dodatkowe parametry to max_value, min_value, max_digits (maks. ilo艣膰 cyfr) i decimal_places (ilo艣膰 miejsc po przecinku)
  • EmailField - pole text na ares email
  • FileField - pole file na dowolny plik
  • ImageField - pole file na plik graficzny, wymaga PIL
  • IntegerField - pole text na liczby ca艂kowite, dodatkowe argumenty: max_value i min_value
  • MultipleChoiceField - podobne do ChoiceField, lecz umo偶liwia wyb贸r wielu opcji. Przyjmuje parametr choices.
  • TimeField - pole na czas, domy艣lnie akceptuje formaty:
    '%H:%M:%S',     # '14:30:59'
    '%H:%M',        # '14:30'
  • URLField - pole na odno艣nik URL.

Formularze z modeli

Klasa forms.ModelForm s艂u偶y do definiowania formularzy generowanych z okre艣lonego modelu. Oto przyk艂ad:
class CommentForm(forms.ModelForm):
	class Meta:
		# Nazwa modelu
		model = Comment

def show_entry(request, slug):
	# pobranie wpisu
	e = Entry.objects.get(slug=slug)
	# formularz komentarzy
	form = CommentForm()
	if request.POST:
		s = Stripper()
		data = request.POST.copy()
		data['entry'] = str(e.id)
		data['date'] = datetime.now()
		data['text'] = s.strip(data['text'])
		data['author'] = s.strip(data['author'])
		form = CommentForm(data)
		if form.is_valid():
			# zapisanie komentarza do bazy
			form.save()
			form = CommentForm()
	return render_to_response(
		'blog/show.html',
		{'e':e, 'form':form},
		context_instance=RequestContext(request))
Powy偶szy przyk艂ad obs艂uguje dodawanie komentarzy do wiadomo艣ci (Entry). Dodatkowo, jako 偶e nie wy艣wietlamy pe艂nego formularza (np. pola relacji do wpisu wy艣wietlanego jako select wszystkich wiadomo艣ci) to musimy przed walidacj膮 danych uzupe艂ni膰 brakuj膮ce dane. W przypadku edycji obiektu do klasy formularza wystarczy poda膰 argument instance z przypisanym obiektem, kt贸ry ma by膰 edytowany.
RkBlog

Django, 14 July 2008, Piotr Mali艅ski

Comment article