25 Mart 2014 Salı

Django'da Formlar - II

Merhaba Arkadaşlar,

Bir önceki blogumda sizlere genel olarak formları anlatmıştım. Burada ise Django'da form mantığını anlatacağım. Bu blogda yapacaklarımızı gördükten sonra aslında geçen blogda yaptıklarımızın bizlere fazladan iş yükü olduğunu göreceğiz. Haydi Django'nun bize ne gibi kolaylıklar sağladığına bakalım. 

Django modelleri kullanarak formları hazırlar. Tüm denetimleri kendisi yapar. Bu ikinci cümlem biraz uçuk gözükebilir ama öyle. Denetimleri kendisi yapıyor, bize sadece kullanmak kalıyor. Bunu bir örnek ile inceleyelim. formlar modeller üzerine kurulur ve uygulama-dosyası/proje-dosyası konumunda forms.py dosyasında belirtilir. Geçen haftalarda üzerinde çalıştığımız okul projesinde Öğretim elemanları için bir form hazırlayalım. Bunun için okul/yonetim/forms.py dosyasını oluşturup aşağıdaki satırları dosyaya yazalım : 


# -*- coding: utf-8 -*-

from django import forms

class OgretimElemaniFormu(forms.Form):
    adi = forms.CharField()
    soyadi = forms.CharField()
    telefonu= forms.CharField(required = False )
    e_posta_adresi = forms.EmailField(required = False)



Form alanlarına isim verirken bunların modelimizdeki isimler ile aynı olmasına dikkat etmeliyiz. Şimdi bu yaptığımız ne anlama geliyor diye ufak bir demo yapalım. Django kabuğumuzu açıp formu inceleyelim : 



>>> from yonetim.forms import *
>>> ogrelmForm = OgretimElemaniFormu()
>>> print ogrelmForm
<tr><th><label for="id_adi">Adi:</label></th><td><input type="text" name="adi" id="id_adi" /></td></tr>
<tr><th><label for="id_soyadi">Soyadi:</label></th><td><input type="text" name="soyadi" id="id_soyadi" /></td></tr>
<tr><th><label for="id_telefonu">Telefonu:</label></th><td><input type="text" name="telefonu" id="id_telefonu" /></td></tr>
<tr><th><label for="id_e_posta_adresi">E posta adresi:</label></th><td><input type="text" name="e_posta_adresi" id="id_e_posta_adresi" /></td></tr>
>>>


Gördüğünüz gibi biz sadece formda bulunacak olan alanları forms.py dosyasında tanımladık, gerisini Django tamamladı. Ayrıca form elemanları yazılan sırada görüntüleniyor olacak. Dikkatinizi çekmiştir tablo açma (<table>) ve kapama (</table>) etiketleri yok. Bunları biz şablon içerisine kendimiz ekleyeceğiz. Bazen şablon içerisinde etiketleri ve alanları teker teker kullanmak isteyebiliriz. Bunun için :

>>> print ogrelmForm['adi']
<input type="text" name="adi" id="id_adi" />
>>> print ogrelmForm['adi'].label
Adi
>>>

Peki ya formdaki herhangi bir alana ön tanımlı değer atamak istersek nasıl olucak? 
Form tanımlanırken initial argümanına değer atanır. Örneğin : 


>>> ondegerler= {'adi':'Bu alana adinizi yaziniz..','e_posta_adresi':'Lutfen e-p
osta adresinizi buraya yaziniz..'}

>>> ogrelmForm = OgretimElemaniFormu(initial=ondegerler)

>>> print ogrelmForm.as_p()

<p><label for="id_adi">Adi:</label> <input type="text" name="adi" value="Bu alan
a adinizi yaziniz.." id="id_adi" /></p>

<p><label for="id_soyadi">Soyadi:</label> <input type="text" name="soyadi" id="i
d_soyadi" /></p>

<p><label for="id_telefonu">Telefonu:</label> <input type="text" name="telefonu"
 id="id_telefonu" /></p>
 
<p><label for="id_e_posta_adresi">E posta adresi:</label> <input type="text" nam
e="e_posta_adresi" value="Lutfen e-posta adresinizi buraya yaziniz.." id="id_e_p
osta_adresi" /></p>

>>>

Peki Django bizim için form denetimi yapar mı? Evet yapar. Nasıl mı? Bu işlemi aslında forms.py dosyasının içerisini doldururken yapmıştık. Şimdi biraz daha inceleyelim : 


# -*- coding: utf-8 -*-

from django import forms

class OgretimElemaniFormu(forms.Form):
    adi = forms.CharField()
    soyadi = forms.CharField()
    telefonu= forms.CharField(required = False )
    e_posta_adresi = forms.EmailField(required = False)

Gördüğünüz gibi yukarda bazı alanlar için required=false argümanını vermişiz. Yani bu alanlar doldurulması zorunlu alanlar değiller. E-posta kontrolu için zaten EmailField metoduna başvurmuşuz. Şimdi bunu test edelim : 


>>> degerler = {'adi':'Osman','e_posta_adresi':'osman@yuksel'}
>>> ogrelmForm = OgretimElemaniFormu(degerler)
>>> ogrelmForm.is_valid()
False

Gördüğünüz gibi Django formun geçersiz olduğunu kontrol etti. Peki hatalar yani eksikliklerimiz neymiş bir de ona bakalım: 


>>> ogrelmForm.errors
{'e_posta_adresi': [u'Enter a valid e-mail address.'], 'soyadi': [u'This field i
s required.']}

İyi hatalarımızı da bize gösteriyor ama bunlar ingilizce diyebilirsiniz. Hiçbir sorun yok çünkü projelerinizi web ortamına taşıdığımız vakit tarayıcının diline çevrilecektir. 

Django formları denetlerken kendi ön tanımlı mekanizmasını kullanır. Ama bazı durumlarda kendi denetim çağrılarımıza ihtiyaç duyabiliriz. Django formları denetlerken, her bir alan için clean_[alan_adi]() işlevine bakar, eğer tanımlı ise işletir. Örneğin e-posta alanında kullanıcı adının root, admin, administrator gibi adresleri kabul etmek istemiyorsak form sınıfını yazarken bunu      -yani clean_e_posta_adresi() işlevini - tanımlamamız gerekir : 

okul/yonetim/forms.py
# -*- coding: utf-8 -*-

from django import forms

class OgretimElemaniFormu(forms.Form):
    adi = forms.CharField()
    soyadi = forms.CharField()
    telefonu= forms.CharField(required = False )
    e_posta_adresi = forms.EmailField(required = False)

    def clean_e_posta_adresi(self):
        adres = self.cleaned_data['e_posta_adresi']
        
        if '@' in adres:
            (kullanici,alan) = adres.split('@')
            if kullanici in ('root','admin','administrator'):
                raise forms.ValidationError('Bu adres gecersizdir !')
        return adres


Şimdi  Django kabuğumuzu yeniden başlatıp deneyelim: 


>>> degerler = {'adi':'Osman','soyadi':'Yuksel','e_posta_adresi':'admin@anadolu.
edu.tr'}
>>> ogrelmForm = OgretimElemaniFormu(degerler)
>>> ogrelmForm.is_valid()
False
>>> ogrelmForm.errors
{'e_posta_adresi': [u'Bu adres gecersizdir !']}
>>>

Gördüğünüz gibi artık kendi denetimimizi de yapabiliyoruz.



Formların Görünümlerde Kullanılması

Geçtiğimiz haftalarda görünümleri ve şablonları öğrenmiştik. Şimdi de formları öğrendik. Artık bunları birarada kullanabiliriz. Önce şablonumuzu hazırlayalım. Geçen haftalarda yaptığımız gibi şablonumuzu yonetim/sablonlar/ konumunda oluşturalım :

yonetim/sablonlar/genel_form_sablonum.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN">
<html>
<head>
<title> {{ baslik }} </title>
</head>

    <link rel="stylesheet" type="text/css" href="/static/django_kitabi.css"/>

<body>
<h1> {{ baslik }} </h1>

{% if form.errors %}
<font color ="red" >
<p>Lutfen hatali/eksik alanlari duzeltip tekrar gonderin
</font>
{% endif %}


<form method ="POST" >
{% csrf_token %}

<table border = "1">
{{ form }}
</table>

<input type="submit" value="Gonder">
</form>
</body>
</html>

Şimdi de ogretim_elemani_ekleme() görünümümüzü aşağıdaki gibi değiştirelim :

def ogretim_elemani_ekleme(request):
    
    if request.method =='POST':
        form = OgretimElemaniFormu(request.POST)

        if form.is_valid():
            temiz_veri = form.cleaned_data
            ogrelm = OgretimElemani(
                adi = temiz_veri['adi'],
                soyadi = temiz_veri['soyadi'],
                telefonu = temiz_veri.get('telefonu'),
                e_posta_adresi = temiz_veri.get('e_posta_adresi'))
            ogrelm.save()
            return HttpResponseRedirect('/ogretim-elemanlari-listesi/')

    else:
        form = OgretimElemaniFormu()

    return render_to_response('genel_form.html',{'form':form,'baslik':'Ogretim Elemani Ekleme'},context_instance = RequestContext(request))



Ama bunu yapmadan önce görünümümüzün olduğu sayfanın başına  from yonetim.forms import *  satırını eklememiz gerekir. Yukarıdaki görünümüzden farkedeceğiniz üzere gelen verilerden zorunlu olmayanları GET ile aldık. Aksi halde hata yükselecektir. Tarayıcımızdan, hatalı bir formu eklemek istediğimiz zaman ekranımız aşağıdaki gibi olacaktır :
Django Form Denetimi


















Eğer doğru bir veri girişi yapmışsak, önce veri kaydedilecek ardından daha önce eklenen öğretim elemanlarının da bulunacağı bir liste ekrana gelecektir : 

Öğretim Elemanları Listesi

















 
Referanslar :
  1. https://docs.djangoproject.com/en/dev/
  2. BAŞER, Mustafa (2013). Django

Hiç yorum yok:

Yorum Gönder