2 Nisan 2014 Çarşamba

Django Form Yapısı

Bir önceki bölümde Formların şablonlar içerisinde kullanarak görünümler ile bağlantısını sağlamıştık. Bu bölümde ise Django'nun bizim için sağladığı kolaylıklardan olan ve form oluşturma işini Django'nun hallettiği form yapısından bahsedeceğiz. Yani biz modelleri oluştururken yaptığımız gibi nasıl bir form istediğimizi söyleyeceğiz. Django formu bizim için oluşturacak.
Form oluşturma işlemini uygulama içerisindeki herhangi bir Python dosyası içerisinde yapabilirsiniz. Ama biz geleneğe bağlı kalarak forms.py dosyası içerisinde oluşturacağız. Şimdi daha önceki hastahane projemiz üzerinden gidiyoruz.
yonetim/forms.py dosyasını oluşturarak içerisine kodları yazıyoruz.
from django import forms

class DoktorFormu(forms.Form):
 adi  =  forms.CharField()
 soyadi  =  forms.CharField()
 telefon =  forms.CharField(required=False)
 eposta  = forms.EmailField(required=False)
Burada ilk olarak django programından formsu içe aktarıyoruz. İçe aktarma yaptığımıza göre artık fonksiyonlarını kullanabiliriz. Oluşturduğumuz form sınıfının model sınıfı oluşturmaya çok benzediğini fark etmişsinizdir. Burada dikkat etmemiz gereken form alanlarına isim verirken modellerimizdeki isimler ile aynı olması gerektiğidir. telefon ve eposta alanlarını oluştururken kullandığımız required=False özelliği isteğe bağlı olduğunu belirtir.
Django kabuğunu açarak formumuzun nasıl olduğunu kontrol edelim.
>>> from yonetim.forms import *
>>> doktorForm = DoktorFormu()
>>> print doktorForm
<tr><th><label for="id_adi">Adi:</label></th><td><input id="id_adi" name="adi" type="text" /></td></tr>
<tr><th><label for="id_soyadi">Soyadi:</label></th><td><input id="id_soyadi" name="soyadi" type="text" /></td></tr>
<tr><th><label for="id_telefon">Telefon:</label></th><td><input id="id_telefon" name="telefon" type="text" /></td></tr>
<tr><th><label for="id_eposta">Eposta:</label></th><td><input id="id_eposta" name="eposta" type="email" /></td></tr>
Django bizim için label(etiket) ve input taglarını kullanarak formu oluşturdu.Buradaki etiketler alan isimlerinden çıkartılır.Django formları tarayıcıda düzgün görünebilmesi için tablo yapısını kullanarak oluşturdu. Ama dikkat etmelisiniz form açma(<table>) ve kapama(</table>) etiketleri bulunmamaktadır. Bu etiketleri şablon içerisinde kendimiz ekleyeceğiz. Formları oluşturmanın tek yolu tablo yapısı değil. Django bize bir kaç alternatif sunar.
Form elemanlarını satır satır bastıralım.
>>> from yonetim.forms import *
>>> doktorForm = DoktorFormu()
>>> print doktorForm
<tr><th><label for="id_adi">Adi:</label></th><td><input id="id_adi" name="adi" type="text" /></td></tr>
<tr><th><label for="id_soyadi">Soyadi:</label></th><td><input id="id_soyadi" name="soyadi" type="text" /></td></tr>
<tr><th><label for="id_telefon">Telefon:</label></th><td><input id="id_telefon" name="telefon" type="text" /></td></tr>
<tr><th><label for="id_eposta">Eposta:</label></th><td><input id="id_eposta" name="eposta" type="email" /></td></tr>
Veya form elemanlarını liste şeklinde de alabiliriz.
>>> print doktorForm.as_ul()
<li><label for="id_adi">Adi:</label> <input id="id_adi" name="adi" type="text" /></li>
<li><label for="id_soyadi">Soyadi:</label> <input id="id_soyadi" name="soyadi" type="text" /></li>
<li><label for="id_telefon">Telefon:</label> <input id="id_telefon" name="telefon" type="text" /></li>
<li><label for="id_eposta">Eposta:</label> <input id="id_eposta" name="eposta" type="email" /></li>
Python bizim için her şeyi biz nasıl istersek o şekilde yapıyor. Oluşturduğumuz bir form içerisinden istediğimiz bir elemanı çekebiliriz.
>>> print doktorForm['adi'].label
Adi
>>> print doktorForm['adi']
<input id="id_adi" name="adi" type="text" />
Varsayılan Değerler
Eğer bir form elemanın sayfa yüklenirken varsayılan bir değer ile yüklenmesini istiyorsanız bunu da sağlayabilirsiniz. Bunun için initial özelliğini kullanacağız.
>>> varsayilan = {'adi':'Adiniz. Bos birakilamaz.'}
>>> form = DoktorFormu(initial=varsayilan)
>>> print form
<tr><th><label for="id_adi">Adi:</label></th><td><input id="id_adi" name="adi" type="text" value="Adiniz. Bos birakilamaz." /></td></tr>
<tr><th><label for="id_soyadi">Soyadi:</label></th><td><input id="id_soyadi" name="soyadi" type="text" /></td></tr>
<tr><th><label for="id_telefon">Telefon:</label></th><td><input id="id_telefon" name="telefon" type="text" /></td></tr>
<tr><th><label for="id_eposta">Eposta:</label></th><td><input id="id_eposta" name="eposta" type="email" /></td></tr>
Artık adi etiketinin value değerinin dolu olduğunu görebilirsiniz.
Formların Kontrolü
Formlar doldurulduktan sonra bizim istediğimiz standartlara göre doldurulup doldurulmadığını kontrol edebiliriz. Eğer bu kontrolü yapmaz isek aldığımız değerleri veritabanına kaydederken standartlara uygun olmadığı için hata ile karşılaşırız. Kontrol etmek için is_valid() metodunu kullanacağız.
>>> gonderilenler = {'adi':'Mustafa','soyadi':'Kemal','eposta':'mustafa@mail.com'}
>>> doktorForm = DoktorFormu(gonderilenler)
>>> doktorForm.is_valid()
True
>>> gonderilenler = {'adi':'Mustafa','eposta':'mustafa@mail.com'}
>>> doktorForm = DoktorFormu(gonderilenler)
>>> doktorForm.is_valid()
False
İlk durumda form hatasız olduğu için True değeri döndürüldü. Fakat ikinci durumda soyadi kısmını zorunlu yapmıştık ve girilmediği için False döndü. Yani form hatalı bir şekilde doldurulmuş. Peki hatalı doldurulan kısımlar nereler? Bunu öğrenebilmek için , errors özelliğini kullanacağız.
>>> doktorForm.errors
{'soyadi': [u'This field is required.']}
Hataları buradan anladık. İngilizce olması önemli değil. Tarayıcıda, tarayıcının diline döndürülecektir.
Django formları kendi mekanizmasına göre denetler. Ama bazı durumlarda denetlemeyi kendi isteğimize göre değiştirmek isteyebiliriz. Bunun için clean_[alanadi]() fonksiyonunu kullanmamız gerekir. Django denetleme yaparken her form sınıfının altındaki bu işleve bakar. Şimdi telefon numarasının 11 karakterden oluşması için bu fonksiyonu yazalım.
class DoktorFormu(forms.Form):
 adi  =  forms.CharField(label="Adınız")
 soyadi  =  forms.CharField(label="Soyadınız")
 telefon =  forms.CharField(label = "Telefon Numaranız:",required=False)
 eposta  = forms.EmailField(label="E-Posta Adresiniz",required=False)

 def clean_telefon(self):
  tel = self.cleaned_data['telefon']
  if tel != "":
   if len(tel) != 11:
    raise forms.ValidationError('Telefon numarasi 11 karakter olmalidir.')
  return tel
Deneyelim.
>>> from yonetim.forms import *
>>> DoktorForm = DoktorFormu({'adi':'Mustafa','soyadi':'Metin','telefon':'5555'})
>>> DoktorForm.errors
{'telefon': [u'Telefon numarasi 11 karakter olmalidir.']}
Gördüğünüz gibi clean_[alanadi]() işlevini kullanarak kendi kontrolümüzü oluşturduk. Sizde istediğiniz bir alan için kontrol yapabilirsiniz.
Kaynakça

3 yorum :

  1. Çok güzel devamını bekliyoruz :)

    YanıtlaSil
  2. Django ile oluşturduğumuz formlarda class nasıl eklenir ve tablo yerine divlerle yapmak istersek nasıl olacak?

    YanıtlaSil
    Yanıtlar
    1. Bunun için widget kullanman gerekiyor. Şöyle örnek verebilirim.
      class LoginForm(AuthenticationForm):
      username = forms.CharField(widget=TextInput(attrs={'class': 'form-control','placeholder': 'Enter Username'}))
      password = forms.CharField(widget=PasswordInput(attrs={'class': 'form-control','placeholder':'Enter Password'}))

      Kullanımı ise yapmanız gereken tek şey div içersinde form elemanlarını yazdırmak
      div> form.username < /div
      div> form.password < /div

      Sil