23 Mayıs 2014 Cuma

Modellerden Form Oluşturma


      Django'da bir veritabanına dayalı bir uygulama geliştirildiğinde Django modellerini ve bu modellere biçim olarak  yakın olan formları kullanırız. Örneğin, daha önce oluşturduğumuz okul projesinde öğretim görevlilerine ait modelimiz aşağıdaki gibiydi :

...
class OgretimElemani(models.Model):
    UNVAN_SECENEKLERI=(('AG', u'Araştırma Görevlisi'),
                       ('DR', u'Doktor'),
                       ('YD', u'Yardımcı Doçent Doktor'),
                       ('DD', u'Doçent Doktor'),
                       ('PD', u'Profesör Doktor'),
                       )
    unvani = models.CharField(max_length = 2, choices= UNVAN_SECENEKLERI,
                              blank=True , verbose_name='Unvanı')
    adi = models.CharField(max_length =50, verbose_name='Adı')
    soyadi = models.CharField(max_length =50,verbose_name='Soyadı')
    telefonu = models.CharField(max_length =10,blank=True,
                                verbose_name='Telefon Numarası')
    e_posta_adresi = models.EmailField(blank = True,verbose_name='E-Posta Adresi')

    def __unicode__(self):
        return u'%s, %s' %(self.soyadi,self.adi)
    class Meta:
        ordering =['soyadi']

...


Daha sonra bu modelde tanımlı alan türlerini formumuzda tekrar tekrar yazıyorduk.
  Yani, aynı alanı hem model içerisinde hemde form içerisinde yazıyorduk. Elbette bu durum form uygulamasının bir modele sahip olmasına bağlıydı. Örneğin geçen hafta üzerinde çalıştığımız arama formu'na ait bir model yoktu. Çünkü arama formu ile etkileşen verileri veritabanına yazmak zorunda değildik ve formumuzu bir modelden bağımsız olarak tasarladık. Şimdi daha önce okul projesinde tasarladığımız OgretimElemani modelimizden formu nasıl oluşturduğumuza bakalım :

...
from django import forms

class OgretimElemaniFormu(forms.Form):
    UNVAN_SECENEKLERI=(('AG', u'Araştırma Görevlisi'),
                       ('DR', u'Doktor'),
                       ('YD', u'Yardımcı Doçent Doktor'),
                       ('DD', u'Doçent Doktor'),
                       ('PD', u'Profesör Doktor'),
                       )
    unvani = forms.ChoiceField(label ="Unvanı",
                               choices= UNVAN_SECENEKLERI, required=False)
    
    adi = forms.CharField(label = "Adı")
    soyadi = forms.CharField(label = "Soyadı")
    telefonu= forms.CharField(label = "Telefon Numarası",required = False )
    e_posta_adresi = forms.EmailField(label = "E-Posta Adresi",required = False)

...


Gördüğünüz gibi formumuz biçim olarak neredeyse modelimizin aynısı.  Şimdi bu ana kadar öğrendiklerimizi bir kenara bırakıp modelden form oluşturalım, yani OgretimElemaniFormu'nu aşağıdaki gibi güncelleyelim :

...
from django.forms import ModelForm
...

class OgretimElemaniFormu(ModelForm):

    class Meta:
        model = OgretimElemani

        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 geçersizdir !')
        return adres
...


Yukarda gördüğümüz iki form da aynı işi yapmaktadır ama ikincisi hem kolaylık sağlıyor hem de kod karmaşasını önlüyor. Modelde alanlara verbose_name argümanını eklediğimizi fark etmişsinizdir. Bu alan modellerden form oluşturulduğu zaman form alanlarına ait etiketleri niteler. Geriye sadece bu formu görünümüzde kullanmamız kalır. Görünümde kullanmadan önce modellerden form oluştururken formda olmasını istediğimiz alanları ya da formdan çıkarmak istediğimiz alanları nasıl belirleyebileceğimize değinmek istiyorum.  Yukarıdaki kullanımda, modelde bulunan bütün alanların formda bulunması durumudur. Örneğin; biz telefon numarasının formda bulunmasını istemediğimizde yapacağımız tek iş aşağıdaki  özelliklerden istediğimizi formumuza eklemek olacaktır :


#formda bulunmasını istediğimiz alanlar
fields = ['adi','soyadi','e_posta_adresi'] 

#formdan çıkarmak istediğimiz alanlar
exclude = ['telefonu']



Yukarıda modelimizi ve bu modele uygun formu tasarladık. Şimdi sıra formu görünümüzde kullanmaya geldi. Django burada da bize kolaylık sağlıyor : Görünümlerde kullandığımız form nesnelerinin kaydetme özelliği vardır. Yani artık verileri alıp veritabanına kaydetmek ile uğraşmak zorunda değiliz. Django bunu bizim için yapacak.

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


...

def ogretim_elemani_ekleme(request):

    ogrElmID = request.GET.get('id')

    if ogrElmID:
        try:
            ogrelm = OgretimElemani.objects.get(id = ogrElmID)
            form = OgreitmElemaniFormu(instance=ogrelm)
            
        except:
            return HttpResponse(u'Aradiginiz ogretim elemani bulunamiyor: ID=%s' % ogrElmID)
    else:
        form = OgretimElemaniFormu()

    
    if request.GET.get('sil'):
        ogrelm.delete()
        return HttpResponseRedirect('/ogretim-elemani-listesi/')
        
    
    if request.method =='POST':

        if ogrElmID:
            form = OgretimElemaniFormu(request.POST, instance = ogrelm)
        else:
            form = OgretimElemaniFormu(request.POST)

        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/ogretim-elemanlari-listesi/')

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


Daha önce hazırlamış olduğumuz öğretim elemanı ekleme görünümü ile kıyaslandığında işlerin gerçek anlamda kolaylaştığı görülür.

Peki bir model'de tanımlanmış alanın varsayılan değerini değiştirebilir miyiz ?
Evet, değiştirebiliriz. Aşağıdaki gibi widgets sözlüğüne değiştirmek istediğimiz alanın adını ve değiştireceğimiz değerini yazarak bunu da halletmiş oluruz :

...

from django.forms import ModelForm
...

class OgretimElemaniFormu(ModelForm):

    class Meta:
        model = OgretimElemani
        widgets = {
        'alan': değeri,
        }

...



Referanslar :
  1. hhttps://docs.djangoproject.com/en/dev/topics/forms/modelforms/
  2. http://www.djangobook.com/

Hiç yorum yok:

Yorum Gönder