Django'da Modellere Giriş

Django'ya bir sure ara verdikten sonra bana gore Django'nun temelini oluşturan model kavramından bahsetmek istiyorum.Modeller Django'nun veritabanı ile bağlantısı oluşturan kısımlar diye duşunebiliriz.Yani veritabanında oluşmasını istediğimiz tabloları,kolonları model olarak tanımlayacağız ve Django bunları direk olarak veritabanına ekleme yapıcak.Bu sayede bir daha veritabanında sql sorgusu ile veritabanı oluşturmaktak kurtulacağız.Bu MVC yapısının bize getirdiği buyuk kolaylıklardan sadece birisi.

django cake

Şimdi daha onceleri oluşturduğumuz uygulamanın içinde oluşan models.py dosyasını açarak buranın içerisine modellerimizi ekleyeceğiz.Ben sıfırdan model yazmak yerine sitemde kullandığım modeller uzerinden gideceğim.Zaten klasik bir blog sisteminde ortalama aynı şeyler olur.

Mesela blog sitemizde Kategoriler ve Yazilar adında iki tablomuz olacak ve bu tabloların içinde aşağıdaki gibi kolonlarımız olacak.

Kategoriler -> baslik,sef_baslik,slug,aciklama,aciklama_sef

Yazilar -> baslik,sef_baslik,slug,aciklama,aciklama_sef,kategori,icerik_anasayfa,icerik,yayindami,etiketler,olusturulma,degistirilme,yazar

Ben biraz fazla kolon kullanmış olabilirim ama siz ihtiyaçlarınız doğrultusunda eklemeler veya çıkartmalar yapabilirsiniz.Zaten aşağıdaki ornek ile eminim kafanızda bir parlama meydana gelecek ve olayı sokeceksiniz.Daha sonra da kendi modellerinizi yazacaksınız.

from django.db import models
from django.contrib.auth.models import User
from tagging.fields import TagField
from tagging.models import Tag
from unidecode import unidecode
from django.contrib.sitemaps import ping_google

class Kategoriler(models.Model):

   baslik           = models.CharField(max_length=255, verbose_name="Baslik", help_text = "Kategori Basligi")
   sef_baslik       = models.CharField(max_length=255, verbose_name="Baslik Sef", help_text = "Baslik Sef", blank=True) 
   slug             = models.SlugField(max_length=255, verbose_name="Slug")

   aciklama         = models.CharField(max_length=500, verbose_name="Aciklama", help_text = "Kategori Aciklamasi")
   aciklama_sef     = models.CharField(max_length=500, verbose_name="Aciklama Sef", help_text = "Aciklama Sef", blank=True)

   def __unicode__(self):
       return self.baslik

   class Meta:
       verbose_name_plural = "Kategoriler"

   def get_absolute_url(self):
       return "/blog/kategori/%s/" %self.slug

   def save(self, *args, **kwargs):
       self.sef_baslik = unidecode(self.baslik)
       super(Kategoriler, self).save(*args, **kwargs)

       self.aciklama_sef = unidecode(self.aciklama)
       super(Kategoriler, self).save(*args, **kwargs)

class Yazilar(models.Model):
   baslik           = models.CharField(max_length=255, verbose_name="Baslik", help_text = "Yazi Basligi")
   sef_baslik       = models.CharField(max_length=255, verbose_name="Baslik Sef", help_text = "Baslik Sef", blank=True) 
   slug             = models.SlugField(max_length=255, verbose_name="Slug")

   aciklama         = models.CharField(max_length=500, verbose_name="Aciklama", help_text = "Yazi Aciklamasi")
   aciklama_sef     = models.CharField(max_length=500, verbose_name="Aciklama Sef", help_text = "Aciklama Sef", blank=True)

   kategori     = models.ForeignKey("Kategoriler", verbose_name="Kategori")

   icerik_anasayfa  = models.TextField(verbose_name="Anasayfa Icerik", help_text = "Anasayfada Gozukecek Icerik")
   icerik           = models.TextField(verbose_name="Tum Icerik", help_text = "Tum Icerik")

   anasayfa_sabit   = models.BooleanField(verbose_name="Anasayfa", default=True, help_text = "Yazi Anasayfa Gozuksun mu?")

   etiketler        = TagField(verbose_name="Etiketler")

   olusturulma      = models.DateTimeField(auto_now_add=True, verbose_name="Olusturulma Tarihi")
   degistirilme     = models.DateTimeField(auto_now=True, verbose_name="Degistirilme Tarihi")

   yazar        = models.ForeignKey(User, verbose_name="Yazar")

   def __unicode__(self):
       return self.baslik

   def save(self, *args, **kwargs):
       self.sef_baslik = unidecode(self.baslik)
       super(Yazilar, self).save(*args, **kwargs)

       self.aciklama_sef = unidecode(self.aciklama)
       super(Yazilar, self).save(*args, **kwargs)

       try:
           ping_google()
       except Exception:
           pass

   class Meta:
       verbose_name_plural = "Yazilar"

   def get_absolute_url(self):
       return "/%s.html" %self.slug

   def get_tags(self):
       return Tag.objects.get_for_object(self)

Yukarıdaki kodlar bizim models.py dosyamızın içerisi olacak.Şimdi sırayla biraz ayrıntıya girelim.

En yukarıda gorduğunuz from ile başlayan satırlar klasik python ile import satırları.Ben burada django'nun user modelini(yazılardaki yazar kısmı için),tagging uygulaması(pip install django-tagging),meta bolumlerinde turkçe karakter sıkıntısını çozmek için unidecode ve yazılarımızı google'a pinglemek için ping_google import ettim.

Biraz aşağıda class Kategoriler satırını goruyorsunuz.Django'da modellerde class ile oluştaracağımız bolumler veritabanında tablo olarak oluşacak.Classların içinde oluşturacağımız field kısımları veritabanında ilgili tablonun kolonları olacak.Djangodaki bu model yapısı ile veritabanı bağımsız çalışabilirsiniz.İsterseniz sqlite,psql,mysql veya oracle kullanın.Tek yapmanız gereken settings.py içindeki db ile ilgili satırı editlemek.

Eğer models.py dosyasını incelerseniz iki adet class oluşturmuşum.Bunlar Kategoriler ve Yazilar.Artık bunlar veritabanındaki tablolarımız olacak.Kategoriler altında oluşturduğum baslik,sef_baslik,slug,aciklama,aciklama_sef fieldler yani alanlar Kategoriler tablomuzun kolonları olacak.Kolonları oluştururken hatırlarsanız mysql'da alan tipi seçimi yapılırdı.Bazı yerlerde char,bazı yerlerde text veya int gibi alanlar seçilirdi.Django'da da bu alanları burada tanımlıyoruz.Oluşturacağınız alanın turunu modeller içinde tanımlamanız gerekiyor.

Django'daki fieldlerin Mysql karşılıkları aşağıdaki gibidir.

Django Mysql

AutoField integer AUTO_INCREMENT

BooleanField bool

CharField varchar(%(max_length)s)

CommaSeparatedIntegerField varchar(%(max_length)s)

DateField date

DateTimeField datetime

DecimalField numeric(%(max_digits)s, %(decimal_places)s)

FileField varchar(%(max_length)s)

FilePathField varchar(%(max_length)s)

FloatField double precision

IntegerField integer

IPAddressField char(15)

NullBooleanField bool

OneToOneField integer

PositiveIntegerField integer UNSIGNED

PositiveSmallIntegerField smallint UNSIGNED

SlugField varchar(%(max_length)s)

SmallIntegerField smallint

TextField longtext

TimeField time

Django'da birçok field turu var.Bunların başında yukarıda yazdıklarım yer alır.Bunların hepsine django'nun resmi sitesinden veya django cheat sheet'den ulaşabilirsiniz.

Bu fieldlerde isimlerden yola çıkarak işlevlerini anlayabiliriz.Örneğin CharField'in mysqldaki char'a ,TextField'in longtext'e eşdeğer olduğunu soyleyebiliriz.Diğerleride veritabanın'ın o bolgesinde kullanmak istediğiniz veriye gore alan oluşturuyor.Örneğin bir blog yazısının içeriğini TextField'da saklayabiliriz.Veya iletişim paneli yaptığınızda cevabın gideceği mail adresini MailField,sitenin açık veya kapalı olduğunu anlamak için BooleanField kullanabiliriz.Bu ornekler çoğaltılabilir.Ayrıntılı bilgiler için kesinlikle resmi siteye bakınız.

Birde bu fieldlerde yer alan verbose_name,help_text,max_length gibi bolumleri anlatmaya gerek yok.Herşey gayet açık.Ancak burada yer alan ForeignKey biraz onemli.Burada yapılan iş aslında gayet basit.Ancak ileride çok fazla kullanacağınız için kesinlikle oğrenmekte fayda var.ForeignKey'i biraz incelediğinizde gorevi belli oluyor.İki tabloyu birbiri ile ilişkilendiriyor.Mesela Yazilar tablosundaki kategori kolonundaki veriyi,Kategoriler tablosundan alıyoruz.Yani birbirleri arasında bir bağ kuruyor.İki tabloyu ilişkilendiriyor.

Field kısımıda hallettikten sonra buraların altında yer alan fonksiyonları biraz inceleyelim.Bizim modellerimiz içinde tanımladığımız fonksiyonlara views içinden de ulaşabiliyor olmamız gerçekten Django'nun çok guzel ozelliklerinden birisi.Bu fonksiyonlar ile çok guzel şeyler yapabilirsiniz.Örneğin yazımızı kaydet dediğimizde google'a pinglettirebilir veya template içinde yazının urline direk buradaki fonksiyon ile ulaşabiliriz.

Burada yer alan unicode ve meta bolumlerini atlıyorum.Çunku bunlar admin panelinde işimize yarayacak kısımlar.Ve tamamen site sahibine kolaylık sağlamak için kullanılıyor.Ama etkin kullanmakta çok fazla fayda var.

Save fonksiyonu onemli ve çok kez kullanacağımız bir fonksiyon.Bu fonksiyon yazıyı kaydet butonuna bastığımız zaman çalıştırılan bir fonksiyon.Ve eğer yazı kaydedilirken yapılması gereken işlemler varsa bunları burada tanımlıyoruz.Mesela ben yazı başlığını alıp turkçe karakterlerden arındırıp sef_baslik alanına eklettiriyorum.Yani "Turkçe Şehirler" olan başlığı "Turkce Sehirler" olarak değiştirip sef_baslik alanına ekliyom.Bu sayede meta kodlarındaki Turkçe karakter sorununu çozuyorum.Sizde aklınıza gelen birçok alanda bu save fonksiyonunu kullanabilirsiniz.

Django Web Framework

Django'da modeller ile temel olarak bilmeniz gerekenler bunlar.Ancak Django'da modeller bu kadar değil.İşin içinde girdikçe Django'nun bize getirdiği harika kolaylıkları keşfediyorsunuz.Mesela veritabanı bağımsız tablo ve kolonlar oluşturmak bana gore çok buyuk bir guzellik.(Tabi bunu yapan başka frameworklerde var) Ama sadece bu kadar değil.Zamanla birçok kolaylık farkedeceksiniz.Mesela Django'nun image ve file fieldleri bana gerçekten çok hoş geldi.PHP'deki gibi bir ton guvenlik uygulamasıyla uğraşmadan direk imagefield ekleyerek resim yuklememizi yapıyoruz.Geri kalan herşeyi Django hallediyor.

Peki Django'da modelleri oluşturduk.Daha sonra ne yapacağız? Tabikide burasıda çok onemli.Modellerimiz içinde yer alan alanlarımızı veritabanına kayıt ettireceğiz.Bunun için kesinlikle sql ile uğraşmıyoruz.Komut satırına giriyoruz ve aşağıdaki komut ile tablo ve kolonlarımızı oluşturuyoruz.İlk oluşturmada mail ve username isteyecek.Bunlar sizin admin kullanıcısı bilgileridir.

python manage.py syncdb

Artık veritabanı tablolarımız ve kolonlarımız oluştu.Bundan sonra uygulamamızı çalıştırmanın bir anlamı yok.Çunku henuz admin panelimize register etmedik.Onuda bu yazıda anlatıp sıkmak istemiyorum.Bir sonraki yazıda Django Admin Paneli ayarlarımızı yapmayı ve oluşturduğumuz tablo ve kolonlarımıza admin panelinden veri eklemeyi,değiştirmeyi,silmeyi anlatacağım.Şimdilik sitenizin veritabanı kısmını hallettik.Biraz zaman sonra da views ve templates olaylarına girip tum işlemleri tamamlayacağız.Ve ekstra işlemlere başlayacağız.

Aşağıdaki resimde geçen uygulama isimlerine de şimdiden alışmanız fayda var diye duşunuyorum.İlerleyen zamanlarda çok kez kullanacaksınız.

Django build  deploy tools, Alex Arshavski

Önemli Not: Yazı içerisinde birçok tablo ve kolon dedim.Şimdilik boyle bilmenizde fayda var.Ama oğrendikten sonra boyle olmadığını anlayacaksınız.

Önemli Not: Burada Django'nun kotu bir yanından bahsetmek istiyorum.Eğer modellerimiz oluşturup syncdb ile dbyide oluşturduktan sonra yeni bir model eklemesi yaparsanız bunların işlenmediğini farkedersiniz.Bu Django'nun bana gore en kotu ozelliğidir.Belki ilerleyen zamanlarda çozulecek ancak şu anda gerçekten Django'nun imajını sarsıyor.Ancak bundan kurtulmak için birçok yol olduğu için korkulcak bir durum yok.Eğer oluşturduğunuz veritabanını silip yeni oluşturursanız bunun uzerine django tum değişiklikleri işleyecektir.Ancak ben bunlarla uğraşamam diyorsanız daha kolay bir yol var.South adındaki uygulama ile veritabanınızı goç ettirebilirsiniz.Bu konu başlı başına bir makele konusu olduğu için şimdi anlatmıyorum ancak bu sorunun South ile çozulduğunu şimdilik bilmenizde fayda var.

comments powered by Disqus