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:

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: Dost臋pnych jest szereg typ贸w p贸l:

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