11 Eylül 2008 Perşembe

Django Notları - 3

Django'da şablon kavramını anlatmadan önce, şablondan ne anlamamız gerektiği konusunu belirginleştirelim. Örneğin, cep telefonlarımızda hazır mesajlar yazıp kaydedebiliyoruz veya daha önce kaydedilmiş olanları gerektiğinde kullanabiliyoruz. "İşteyim, döneceğim", "Beni 10 dakika sonra ara." gibi bence gereksiz olan bu hazır mesajlar şablon diye geçiyor.

Ama Django'daki şablonlarımız, projemizin çok önemli bir parçası olarak karşımıza çıkıyor. Bir veya birkaç değişkene, bütün veya parça halinde html kodlarını yazmak; tanımladığımız fonksiyonları o değişkene çağırmak ve bu kodu yorumlatmak, kodu hem çirkinleştirecek; hem de projenin gelişimini çok zorlaştıracaktır.

Şimdi saat bilgilerini ekrana yazdırdığımız fonksiyonun kodlarını ve urls.py dosya içeriğini tekrar verelim. views.py dosyamız:

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

from django.http import HttpResponse
import datetime

def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>Saat ve tarih bilgisi: %s.</body></html>" % now
return HttpResponse(html)


urls.py dosyamız:

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

from django.conf.urls.defaults import *
from mysite.views import current_datetime

urlpatterns = patterns('',
(r'^time/$', current_datetime),
)



Burada html değişkenine atadığımız html kodu kısa:

<html><body>Saat ve tarih bilgisi: %s.</body></html>

Şimdi bu kodu, html uzantılı olarak ayrı bir yere kaydedelim:

<html>
<head>
<title>Merhaba Django!</title>
<style>

body {background-color: #aaa}
p {font-size: 12px}
</style>
</head>
<body>
<p>Cancanlı django'muzla zaman bilgilerimizi öğrenelim: {{ zaman }}</p>
</body>

</html>


Birşey dikkatınızı çekti mi? {{ zaman }} diye birşey yazdık, nedir o? Hayır, html ile ilgili bir özellik değil. Şimdi proje dizinimizde templates diye bir alt dizin oluşturalım ve bu kodu zaman.html olarak, bu alt dizinin içine kaydedelim. Sıra geldi, Django'muza şablon dizinimizin nerede olduğunu tanımlamaya. settings.py dosyasını açın ve şu satırları bulun:

[...]

ROOT_URLCONF = 'negzelfoundation.urls'

TEMPLATE_DIRS = (
)

[...]


TEMPLATE_DIRS tüpüne, templates dizinimizi eleman olarak yazmamız gerekiyor. Burada python bilgilerinizi istediğiniz gibi kullanabilirsiniz. İsterseniz, os.path modülünü çağırıp yapabilirsiniz, şu şekilde:

[...]
import os.path

[...]
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
[...]


replace'in ne işe yaradığını umarım biliyorsunuzdur. Posix standardındaki işletim sistemlerinde sanırım ona gerek yok. Ama siz de benim gibi, bunun için os.path import etmeye gerek yok derseniz, şu şekilde de templates dizinini Django'ya göstertebilirsiniz:

[...]
ROOT_PATH = "/proje/dizin/yolunu/buraya/yazin"

[...]
TEMPLATE_DIRS = (
'%s/templates' % ROOT_PATH,
)
[...]


Buraya kadar tamam; ama hala {{ zaman }}'ın ne olduğunu hala söylemedik. Şimdi views.py dosyasındaki current_datetime fonksiyonunu, gerekli modülleri çağırıp tekrar tanımlayalım:

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

from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
now = datetime.datetime.now()
t = get_template('zaman.html')
c = Context({'zaman': now},)

html = t.render(c)
return HttpResponse(html)


get_template, şablonu çağırmak için; Context ise, fonksiyonda tanımladığımız değişkenleri, şablonumuzdaki {{ zaman }} gibi ifadelere bağlamamız için çağrıldı. Sonra, html değişkeninde bağlamları şablonda çevirtip, bir sonraki satırda da bu değişkeni döndürüyoruz. Bakalım nasıl dönmüş:

Cancanlı Django'da Zaman

Huh, iyi eğleniyoruz ;-).

Şablonlarda Etiketler



Örnek olarak oluşturduğumuz zaman.html şablosunda bildiğiniz gibi css, javascript ve html kodlaması yapabilirsiniz. Fakat zaman zaman PHP'de olduğu gibi, belli bir şarta bağlı olarak tekrar edilmesi istenen veya koşulun yerine getirilip getirilmediğine göre değişen fonksiyon cevapları ihtiyacı duyabiliriz:

[...]
<ul>
{% hede fonksiyonu tamamlandığı sürece %}
<li>{{ hede }}</li>
{% döngü sonu %}
</ul>
[...]


Şimdi şöyle bir örnek yapalım. Üç satırlık bir liste oluşturalım, ilk satırda şuanki saat, bir sonrakinde bir saat sonraki saat, ondan sonrakinde de iki saat sonraki saati yazdıralım. İlk olarak, views.py dosyamızda bizim için gerekli modülleri çağıralım:

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

from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime


clock_list isimli fonksiyonumuzu oluşturalım. Örneğimiz için sadece saat bilgisini almak bizim için yeterli:

def clock_list(request):
time = int(datetime.datetime.now().hour)


Sonra, fazla kafamızı bulandırmadan; şimdilik neden, niçin demeden, sonradan oluşturacağımız saat.html isimli şablonu çağırıp, saat değişkenimizi (time) şablona gömerek sayfayı döndürelim:

def clock_list(request):
time = int(datetime.datetime.now().hour)
time_list = []
phrase_list = []
for x in range(3):
time_list.append(time + x)
phrase_list.append("%s saat sonra, akrep %s gösterecek." % (x, time_list[x]))

t = get_template('saat.html')
c = Context({'phrases': phrase_list},)
html = t.render(c)
return HttpResponse(html)



Evet. Ama daha saat.html isimli örnek şablonumuzu oluşturmadık. Örnek olarak yazım templates dizinine alalım:


<html>
<head>
<title>Merhaba Django!</title>

<style type="text/css">
body {background-color: #e0ffb8}
ul {border: 1px solid #333; padding: 0}
li {border: 1px solid #aaa; list-style-type: none}
</style>
</head>
<body>
<center>

<ul>
{% for phrase in phrases %}
<li>{{ phrase }}</li>
{% endfor %}
</ul>
</center>
</body>

</html>


<ul> tagı içinde bi for döngüsü yazmışız, farkettiniz mi? views.py'de tanımladığımız clock_table fonksiyonumuzda oluşturulan listenin her bir elemanı için ekrana bir liste elemanı yazdırıyoruz. Üç adet liste için belki değmez, belki de statik sonuçlar için bu kadar atraksiyonu gereksiz bulabiliriz; fakat sonucu değişebilecek, 100 maddelik bir listeyi yazmayı pek göze alacak değiliz, biz pratik programcılar için..

Evet, saat.html dosyamız da hazır. Son olarak bu fonksiyonu bir sayfaya atayalım. urls.py'yi düzenliyoruz:


from django.conf.urls.defaults import *
from mysite.views import clock_list, current_datetime, hours_ahead

urlpatterns = patterns('',
(r'^clocks/$', clock_list),
(r'^time/$', current_datetime),
(r'^time/artir/(\d{1,2})/$', hours_ahead),
)


Nereye atamışız? http://adresimiz/clocks/ sayfasına.. python manage.py runserver ile sanal sunucumuzu çalıştırıp http://127.0.0.1:8000/clocks/ adresinden bir bakalım nasıl olmuş:

Saat Listesi

Eh, bu da fena değil. Biz burada döngülerin nasıl kullanılacağı üzerine, for ile bir örnek göstererek öğrenmiş olduk. if'tir, else'tir, ifequal ve benzeri diğer döngülerdir, bunların hepsi aynı mantıkla yazılıp kullanılmaktadır. Bu konuda teker teker örnek vermek yerine, şu1 linkteki kodları incelemeniz, sizin için fazlasıyla yeterli olacaktır. Eğer yine de değinilmesini istediğiniz önemli bir nokta varsa, bunu bize bildirmekten çekinmeyin.

2 yorum: