Python tabanlı yeni nesil Web uygulamaları geliştirme platformu

Django (JANG-o diye okunur), modüler, pragmatik bir tasarımla hızlı bir şekilde web uygulamaları geliştirmenize olanak sağlayan açık kaynak kodlu bir web uygulamaları geliştirme platformudur.

Django’nun temel prensibi, uygulama geliştirme sürecini olabildiğince otomatize ederek tekrarları ortadan kaldırmaktır. Bunu yaparken de yolunuza çıkıp özgürlüğünüzü kısıtlamaz.

Yazılım mimarisi olarak Model – Template – View (MTV*) yapısındadır. Buradaki “view” terimini “görünüm”den çok “amaç” veya “uygulama” gibi algılamak daha doğru olur. Bu yapı, veri yapımızı ifade eden model katmanının, kullanıcıların etkileşimini sağlayan görsel arayüzümüzden şablonlarla ayrıldığı ve aradaki bağlantının uygulama katmanımız ile sağlandığı bir yapıdır. Katmanların birbirinden net bir şekilde ayrılması bize esneklik ve modülerlik sağlar. (MTV yerine bazen, temelde aynı mimari ayırımı ifade eden MVC [Model – View – Controller] deyimi de kullanılır.)

Bir uygulamanın veri modelini nesneler olarak tanımlarsınız ve SQL yazmadan istediğiniz nesnelere kolayca ulaşmanızı sağlayan zengin bir veritabanı erişim ara yüzünüz olur. Tabi isterseniz SQL yazmanızı engelleyen bir şey de yok. Veritabanı soyutlaması sayesinde popüler veritabanlarına aynı arayüz ile erişebilirsiniz.

URL tasarımı Web uygulamanızın kalitesini gösteren önemli bir noktadır. Django, hiçbir platform kısıtlaması olmaksızın URL ‘lerinizi istediğiniz gibi tasarlamanıza olanak verir. Regular Expression ‘lar ile ifade ettiğiniz URL paternlerini fonksiyonlarınız ile ilişkilendirirsiniz.

Django’nun genişletilebilir esnek ve güçlü şablon sistemi, görsel tasarım ile içeriği tamamen ayırmanızı sağlar.

Kaşe (Cache) sistemi, uygulamanızın istediğiniz yerlerini kaşelemenizi sağlar. İsterseniz tüm bir sayfayı, isterseniz maliyetli bir sorgunun sonucunu kaşede saklayabilirsiniz. Geri planda isterseniz memcached kullanarak hafızada, isterseniz veri tabanında veya başka bir şekilde kaşeleme yapabilirsiniz. Django istediğiniz kaşe sistemini standart bir ara yüz ile kullanmanızı sağlar.

Django sizi yönetici ara yüzleri hazırlama angaryasından da kurtarır. Uygulamanızın modellerini oluşturduğunuzda, içerik yönetimi ara yüzleri de otomatik olarak oluşturulur.

Uygulamalarınızın farklı dilleri desteklemesini sağlamanız da Django ile çok kolay. Django sizin için tercüme edilmesi gerekenleri hazırlar ve uygulamada hiçbir değişiklik yapmaksızın, sadece tercüme dosyalarını temin ederek farklı dilleri desteklemenize olanak verir.

Şimdi bu bahsettiklerimi bir örnekte göstermeye çalışacağım. Burada amacım tam çalışan bir uygulama yaratmaktan çok Django’nun işleyişi ile ilgili fikir vermek.

Örneğimiz bir blog uygulaması olsun. Bu uygulamada konularına göre bloglar ve blogların içinde kullanıcılara ait yazılar olsun.

Blog nesnemizin modelini şu şekilde tanımlıyoruz:

class Blog(models.Model):
    title = models.CharField(max_length=100)
    is_featured = models.BooleanField(default=False)

Görüldüğü gibi, blogumuzun bir başlığı, bir de öne çıkarılıp çıkarılmayacağını belirten iki tane niteliği (attribute) var. Modelleri veritabanında tablolara karşılık geliyor gibi düşünebiliriz. Nitelikler ise bu tablodaki kolonlardır. Niteliklere verdiğimiz alan (field) tiplerinin veritabanında bir karşılığı vardır. Ancak bunlar her zaman birebir örtüşmek durumunda değildirler. Örneğin EmailAddressField gibi daha özel tipler de kullanabiliriz. Bir EmailAddressField, veritabanında bir karakter alanına karşılık gelse de, içinde tutabileceği değerlerin sadece geçerli e-posta adresleri olması Django tarafından sağlanır.

Şimdi blog yazıları için bir model yaratalım.

class Entry(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()
    blog = models.ForeignKey(Blog)

Burada da blogumuzda yer alacak yazıların bir başlığı, bir ana metni olacağını ve bu yazıların blog modeli ile ilişkilendirileceğini ifade etmiş olduk.

Modellerimizi oluşturduktan sonra komut satırından “syncdb” dediğimiz zaman, veritabanımızda bizim için 2 tane tablo yaratılacak.

Artık uygulamamızın modellerine nesne mantığı içinde ulaşabilir ve yeni nesneler yaratabiliriz.

Örneğin “güncel” başlıklı bir blog yaratıp, bu blog içine bir yazı eklemek şu şekilde yapılabilir:

b = Blog(title=’güncel’)
b.save()

e = Entry(title=’ilk yazı’, body=’Django ile hayat daha kolay’, blog=b)
e.save()

Daha sonra nesnelerimize şu şekilde ulaşabiliriz:

b = Blog.objects.get(title=’güncel’)

entries = Entry.objects.filter(blog=b)

veya

entries = b.entry_set.all()

Bir kere veri modelimizi tanımladıktan sonra, verileri yaratacak ve kullanacak olan fonksiyonları yazıp URL’ler ile ilişkilendirmemiz gerekmekte. Örneğin bir blog’un altındaki yazıları listeleyen bir sayfamız olsun istiyoruz. Bunun için regular expression kullanarak bir URL paterni tanımlıyoruz:

urlpatterns = patterns('',
     …
    ('^blog/(?P<blog_id>d+)/$', 'blog.views.entry_list'),
     …
)

Böylece, örneğin “/blog/1/” URL’ine ulaşılmak istenildiğinde, “entry_list” fonksiyonumuzun blog_id=1 parametresiyle çağırılmasını sağlamış oluyoruz.

“entry_list” fonksiyonumuz da blog_id parametresini alıp, gerekli yazı nesnelerin çekip, bir şablon ile render ederek bir HttpResponse nesnesi döndürmelidir. Böyle söyleyince karışık gibi gelse de gerçek uygulama çok daha kısa:

def entry_list(request, blog_id):
    blog = Blog.objects.get(id=blog_id)
    return render_to_response(‘blog/entry_list.html’,
                                              {‘entries’: blog.entry_set.all()})

Bu fonksiyonumuz id’sini aldığımız blog’un içindeki yazılardan bir konteks yaratıp bunu “entry_list.html” şablonu ile render etmiş olduk. Şablonumuz “entry_list.html” ise şu şekilde olabilir:

{% for entry in entries %}
    **{{ entry.blog.title }}: {{ entry.title }}**

    {{ entry.body|truncatewords:50 }}
{% endfor %}

Bu şablon, kendisine gönderilen “entries” listesi içinde döngüye girerek, yazıların ait olduğu blogun ve yazının başlığı ile yazının metninden ilk 50 kelimeyi basacaktır.

Sadece Django’nun web uygulamalarına yaklaşımı ile ilgili fikir vermek amacıyla kısa örneklendirmeye çalıştıysam da olanakların bununla sınırlı olmadığını özellikle belirtmek isterim. Beni etkileyen en önemli özelliklerinden bir tanesi her noktasının kullanıcı tarafından geliştirilmeye açık olmasıdır.

Django size hayatınızı kolaylaştıracak araçlar vermekle kalmaz, ihtiyaçlar çıktıkça bu araçlara yenilerini ekleyebilmenizi sağlayan açık bir platform da sağlar.

Uygulamalarınızı farklı projelerde tekrar tekrar kullanabilirsiniz. Ayrıca başka uygulamaları da kendi projelerinize rahatça entegre edebilirsiniz, çünkü Django uygulamaları aynı mimari yapıyı taşır.

Django vs. PHP

Ben, 10 yılı aşkın bir süredir ağırlıklı olarak web uygulamaları geliştiren bir yazılımcıyım. PHP3 zamanından 1-2 sene öncesine kadar da tercihim hep PHP olmuştu. İstediğim herşeyi yapabiliyordum. Kendi kütüphanelerimi geliştirmiştim. Bir çok açık kaynak kodlu projeden faydalanabiliyordum. Zaten bütün dünyada PHP rüzgarları esiyordu. Ben de o rüzgarla yolumu alıyordum.

Ama bazı rahatsızlıklarım vardı. Tekrar tekrar aynı kod parçalarını yazıyordum. Bunu olabildiğince engellemek için kütüphaneme genel maksatlı çeşitli nesneler ekledim.

URL ‘lerin yapısı hoşuma gitmiyordu. Bunun için server konfigurasyonu ile oynayarak tüm istemci isteklerinin önce bir PHP dosyasına girmesini ve oradan ilgili fonksiyonlara yönlendirilmesini sağlayacak bir yapı kurdum. Böylece “/blog/guncel/” gibi temiz görünümlü URL ‘ler kullanabilmeye başladım.

Bunun gibi bir takım zorlamalarla PHP’yi istediğim çizgiye çekmeye çalışıyordum ki, Django ile tanıştım. Yapmaya çalıştığım şeylerin daha kapsamlı ve tutarlı biçimleriyle zaten Django’da var olduğunu gördüm. İnsana yıllarca tecrübe edindiği bir dili bırakmak zor gelebilir, ama ben yapmaya çalıştıklarımın doğru olduğunu anladım. Başkaları da bu sorunları yaşamış ve konuyu temelden farklı bir yaklaşımla çözmüşlerdi. Kendim bu sorunları bu kalitede çözemiyordum. Django, herşeyden önce, nesne tabanlı yaklaşım doğasının bir parçası olan Python ile yazılmıştı. Ayrıca arkasında web uygulamaları geliştirmenin problemlerini şık bir şekilde çözmeye odaklanmış geniş ve aktif bir grup vardı. Denemeye karar verdim.

Bu kişisel geçmişimi anlatan girişten sonra önemli ördüğüm noktalarda bu iki teknolojiyi karşılaştırmaya çalışacağım.

Benim için Django’nun en büyük artılarından bir tanesi herşeyin yerli yerinde olması. Cefakar PHP geliştiricilerinin alışık olduğu, projenin yönetilebilirliğini son derece düşüren HTML içerisinde SQL ‘e kadar herşeyin her yerde olabildiği kargaşa yok. Bu sayede hem kendi kodlarınızı - ve kafanızı - düzenli tutabiliyorsunuz hem de başkalarının yazdığı kodu anlamanız ve kendi projenize entegre etmeniz birkaç dakika sürüyor.

PHP ‘nin fonksiyon isimlerinde standart olmayışı ve ad alanı (namespace) yokluğu işleri daha da karıştırıyor. Herhalde PHP ekibi yakında yeni fonksiyon ismi bulamayacak.

İtiraf edeyim, Python’un söz dizimini ilk başta yadırgamıştım. Ama kodu ne kadar bir bakışta anlaşılır kıldığını gördüğümde benimsedim ve gün geçtikçe de daha çok hoşuma gitti.

PHP de Python/Django da açık kaynak kodlu. Ancak PHP ‘yi yüksek trafikli bir uygulamada kullanmak için ticari bazı yazılımlar ile yapınızı desteklemeniz gerekiyor. Bu da PHP ‘nin açıklığını gölgeliyor. Bunun yanında Django sadece tüm kaynak kodu olarak değil geliştirme süreci olarak da tamamen açık. İstediğiniz kadar Django ‘nun geliştirilmesine de dahil olabilirsiniz.

Uygulama taşınabilirliği açısından PHP ‘yi son derece başarısız. Konfigürasyon programcılar için bir kabusa dönüşmüş durumda. “if(get_magic_quotes_gpc())...” yazmaktan bıkmayan bir PHP kullanıcısı var mı?

Django ile kendi makinenizde MySQL ‘de uygulamanızı geliştirin, veritabanı kaşesi kullanın, uygulama sunucusunda veritabanınız PostgreSQL olsun, kaşeniz ise memcached: Tek değişiklik konfigürasyon dosyasındaki birer satır olacak. PHP’de de benzer bazı soyutlamalar sağlayan ara katmanlar var. Yine bir eksiklik, bir başka yama ile örtülmeye çalışılmış oluyor.

PHP nesne tabanlılık konusunda epey yol almış olsa da hala çeşitli kısıtlamalar var. Zaten PHP ‘ye nesne desteği “PHP’de bu da olsun” olarak, bir eksikliği gidermek için eklenmişken, Python gerçek anlamda tümüyle nesne tabanlı. Örneğin türettiğiniz nesnelerin tüm özelliklerini değiştirebilir, çoklu kalıtım (multiple inheritence) gibi özelliklerden faydalanabilirsiniz.

“PHP bir dil, Django bir çatı; elmalarla elmaları karşılaştıralım” diyebilirsiniz. Ama PHP hiçbir zaman gerçek bir dil olarak tasarlanmadı. Web uygulamalarına yönelik işleri çözmek için geliştirilen, C ‘den Perl ‘e birçok farklı dilde yazılmış kütüphane’yi bir araya getiren bir birleştirici oldu. Herkesin ihtiyaç doğdukça yeni özellikler eklemesiyle bugünkü tutarsız kargaşa yaratılmış oldu.

PHP hata yönetimi bakımından da tutarlılık göstermiyor. Dilin yapısından kaynaklanan birçok bug kaynağı (‘0’ == null gibi) mevcut. Bir forumdan alınan soldaki ekran görüntüsündeki son konuların başlıkları, iki dilin (ve kullanıcılarının) hata yönetimine yaklaşımlarını hoş bir şekilde özetliyor.

PHP, Python/Django ‘ya göre daha yaygın olarak kullanılıyor. PHP ile yazılmış hazır bir blog uygulaması bulmanız daha kolay olacaktır. Ama bir blog yazmak yukarıda gösterdiğim kadar kolayken neden başkasının yazdığını kullanmak isteyesiniz? Üstelik Django’da bulduğunuz bir uygulamayı kendi projenize entegre etmeniz çok daha kolay ve pürüzsüz olacaktır. Zengin ve kaliteli Python kütüphaneleri de her zaman elinizin altında.

PHP ‘nin yaygınlığı ucuz hosting çözümleri bulmakta bir avantaj sağlıyor. Ayda $2 ‘lik bir hosting paketinde genellikle Python/Django bulunmuyor. Bu küçük / kişisel projelerde PHP lehine bir durum yaratıyor.

Performans açısından da, Django, kendisi gibi MVC yapısındaki bir çatı olan Ruby on Rails ‘in sitesinde yayınlanan bir karşılaştırma testinde Rails ‘den ve PHP+Symfony‘den kat kat iyi sonuç vermştir. (http://wiki.rubyonrails.com/rails/pages/Framework+Performance)

Bundan 10 yıl önce, herşeyin Microsoft olduğu bir dünyada, PHP nefes alacak bir alan sağlamıştı. Bir çoğumuz web teknolojilerinin temel prensiplerine onunla hakim olduk, pek çok projeler gerçekleştirdik. Ulaştığı yaygınlık, tıpkı çoktan ölmüş yıldızların ışıklarının hala bize gelmesi gibi, bir süre daha parladığını düşündürtebilir ama bugün bana göre görevini tamamlamıştır.

Django’nun şu anki resmi sürümü 0.96 ‘dır. Bu sizleri altyapının sağlamlığı ile ilgili endişelendirmesin çünkü yüksek trafikli birçok web sitesinde uzun zamandır kullanılmaktadır. Ayrıca açık kaynak kodlu hale gelmesinden bu yana 2 seneyi aşkın zaman geçmesine rağmen temel yapısal bir değişiklik geçirmemiş, sadece yeni özellikler kazanmıştır. Bu da tasarımının ve işleyiş biçiminin doğruluğunu göstermektedir. Nitekim pek çok web platformu, böyle süreler sonunda tamamen yeniden yazılma sürecine girmiş, çoğu da bu süreçten bir daha çıkamamıştır.

Eğer umduğum gibi iştahınızı kabartmayı başardıysam buradan sonra aşağıdaki linklerden devam edebilirsiniz. Ayrıca Python’a yabancıysanız, Dive Into Python adresindeki online dokümanlar ile kolay bir giriş yapabilirsiniz.

http://djangoproject.com http://django-tr.com