2 Aralık 2013 Pazartesi

Django'da Şablonlar-1


Merhaba arkadaşlar,

Geçen hafta sizlerle Django'da görünüm oluşturmayı ve bu görünüme adres (url) hazırlamayı öğrendik. Bu hafta ise Django'da  şablonları öğrenelim istedim. Şimdiye kadar tasarımı dahi kodlamayla yaptık. Yani bir gün yaptığımız sayfanın görünümünü değiştirmek istersek; bu değişimi Python kodlarını düzenleyerek yapmamız gerekir. Ama bir şablon oluşturarak kodlama ve tasarımı birbirinden ayırabiliriz. Bunun için Django şablon sistemini kullanalım. Django'nun şablon sistemini anlamak için etkileşimli kabukta biraz çalışalım. Bunun için komut satırına aşağıdaki komutu yazarak Django kabuğunu açalım.

C:\djangoprojeleri\deneme > C:\Python27\python.exe manage.py shell

Şimdi basit ama şablon kavramını kavramamıza yardımcı olacak bir örnek yapalım.

>>>from django import template
>>>x= template.Template("Dersin Adı {{ adı }}.")
>>>y= template.Context({'adı':'Django'})
>>>print x.render(y)
Dersin Adı Django.


Burada şablon x nesnesine şablon, y nesnesine ise bağlam diyoruz.Bağlam içerisindeki {{ ile }} arasındaki değişkenlere de bağlam değişkeni diyoruz. x.render(y) işlemine ise x şablonunun y bağlamı ile yorumlanması diyoruz. Bir şablon nesnesi birden fazla bağlam ile yorumlanabilir.

Şimdi bir şablona basit bir şekilde bir Python sözlüğünü aktaralım:

x = template.Template("""<html><head><title>{{ baslik }}</title>
</head>
<body>
<br>Dersin Kodu: {{ kod}}
<br><b>Dersin Adi:</b>{{ adi }}
<br>Dersin sinifi: {{ sinifi}}
</body>
</html>""")

>>> veri = {"baslik":"Ders bilgileri","kod":"BIM222","adi":"Django","sinifi":"B7",}

>>> y = template.Context(veri)

>>> print x.render(y)
<html><head><title>Ders bilgileri</title>
<body>
<br>Derd Kodu: BIM222
<br><b>Ders Adi:</b> Django
<br>Dersin sinifi: B7
</body>
</html>

Eğer bağlamda olmayan nesne ya da nesne özelliklerini kullanırsak Python'daki gibi hata vermez sadece boş olduğunu gösterir.

Yukarıda sadece şablona bağlamlar ile veri aktardık ve şablon içerisinden bu veriye ulaştık. Ancak web uygulamalarında şablonlar içerisinde bir takım temel programlama etiketlerine ihtiyaç duyarız.Bunlardan en çok kullanılan iki tanesini inceleyelim.

if / else ETİKETİ

{% if %}  etiketi diğer programlama dillerinde olduğu gibi burda da koşulları kontrol etmek için kullanılır.
Temel yapısı şöyledir:
{% if   ___ %}
           ...
{% elif___  %}
           ...
{% else  %}
           ...
{% endif  %}

for ETİKETİ
Şablon içerisinde kullanabileceğimiz tek döngü for döngüsüdür. Örneğin takım kadrosunda bulunan futbolcuların listelenmesi için aşağıdaki gibi bir döngü kullanırız.


<ul>
{% for futbolcu in kadro %}
    <li>{{ futbolcu.isim}}</li>
{% endfor %}
</ul>


for döngüsü ile tersten de iterasyon yapılabilir. Bunun için {% for obj in list reversed %} yapısı 
kullanılır. Bazı önemli for döngüsü değişkenleri şunlardır:


forloop.counter        döngü sayacı değişkenimizdir (1'den başlar)
forloop.counter0       döngü sayacı değişkenimizdir (0'dan başlar)
forloop.revcounter     Sayacı tersten almak içim (1'de sonlanır)
forloop.revcounter0    Sayacı tersten almak içim (0'da sonlanır)
forloop.first          Döngünün başını kontrol etmek için kullanılır
forloop.last           Döngünün sonunu kontrol etmek için kullanılır


Django şablonları içerisinde  karşılaştırmaları or, and, not, in gibi işleçlerle birleştirebiliriz. Kullanımı Python'daki gibidir.

FİLTRELER
Django şablonları içerisinde kullanılabilecek birçok filtre ile birlikte gelir. Ama hepsini anlatma şansım malesef yok. Bu yüzden en çok kulanılanlarını açıklamaya çalışacağım. Bir çok filtre argüman almamakla birlikte genel bir kullanım şekli vardır. Şöyle ki:

{{bağlam_değişkeni | filtre : filtre_argümanı }}

add 
İki argümannı toplar. Örneğin;  {{ değer | add : "2"}}

capfirst
Verilen değerin ilk harfini büyük harfe çevirir.Örneğin; {{ "django" | capfirst }} çıktısı "Django" olur.

cut
Verilen string değişkeninden silinmesi istenen değerler silinir. Örneğin  {{"   Ahmet Amca'nın evi    "| cut :" "}}
"AhmetAmca'nınevi " değerini döndürür.

length
Verinin uzunluğunu verir.

lower - upper
Küçük - büyük harf dönüşümünü yapar.

random
Listeden rastgele eleman seçer.

time
datetime biçimindeki zamanları göstermek için kullanılır.

urlize
Bir metindeki adresleri url biçiminde ifade eder.

ve daha birçok filtre ve etiket bulunmaktadır. Bunların tamamına https://docs.djangoproject.com/en/dev/ref/templates/builtins/#built-in-filter-reference adresinden ulaşabilirsiniz.

Şimdi de şablon içerisine Python kodunun nasıl yazıldığı ile bir örnek yapalım.İlk olarak views.py dosyamıza aşağıdaki satırı yazarak başlayalım.

from django.template import Template, Context

Şimdi de views.py 'ye görünümümüzü ekleyelim.

def notlar(request):
    ogrenciler =((u'Kadir',u'Guler',40,85,75,True),
                 (u'Ahmet',u'Baba',22,58,36,False),
                 (u'Suzan',u'Keskin',65,75,95,True),
                 (u'Ufuk',u'Hakan',45,15,36,False),
                 (u'Hayrettin',u'Öğüt',50,69,50,True),
                 (u'Mehmet',u'Kaan',42,85,25,True),
                 (u'Ayşe',u'Sanem',35,90,75,True),
            )
    s=Template(u'''<table border="1">
        <tr><th> Sıra </th><th> Adı </th>  <th> Soyadı </th> 
        <th> Vize </th> <th> Ödev </th><th> Final </th><th> Başarı Durumu </th><tr>
        {% for ogr in ogrenciler %}            
            <tr><td>{{forloop.counter}}</td>
            <td>{{ogr.0}}</td>
            <td>{{ogr.1}}</td>
            <td>{{ogr.2}}</td>
            <td>{{ogr.3}}</td>
            <td>{{ogr.4}}</td>
            <td>{% if ogr.5 %} BAŞARILI
                {% else %}     BAŞARISIZ
                {% endif %}
            </td></tr>
        {% endfor %}
        </table>''')

    b = Context({'ogrenciler' : ogrenciler})
    html = s.render(b)
    return HttpResponse(html)

Şimdi de var olan görünüme adres atayalım. Geçen haftalardan hatırlayacağınız üzre bu işlemi urls.py dosyası içerisinde yapıyorduk. urls.py dosyasında urlpatterns değişkenine aşağıdaki satırını ekleyelim:

 url(r'^notlar',views.notlar),

Daha sonra komut satırından Django web sunucusunu çalıştıralım ve tarayıcımızdan
-----------------------------------------------------------------------------------------------------
http://localhost:8000/notlar/
-----------------------------------------------------------------------------------------------------
adresine gidelim. 


















Aslında şablonlar böyle  kullanılmaz ama bizim şu ana kadar yaptıklarımız şablonları daha iyi anlamak içindi. Yani şablonları ayrı bir dosyaya yazmadığımız sürece yazdıklarımız bir anlam taşımamaktadır. O halde şablonu proje klasörümüz içerisine C:\...\deneme\deneme\sablonlar  klasörüne notlar.html diye kaydedelim.

notlar.html

<html>
<head>
    <title> Öğrenci Not Listesi</title>
</head>
<body>
    <table border="1">
        <tr><th> Sıra </th><th> Adı </th>  <th> Soyadı </th> 
        <th> Vize </th> <th> Ödev </th><th> Final </th><th> Başarı Durumu </th><tr>
        {% for ogr in ogrenciler %}            
            <tr><td>{{forloop.counter}}</td>
            <td>{{ogr.0}}</td>
            <td>{{ogr.1}}</td>
            <td>{{ogr.2}}</td>
            <td>{{ogr.3}}</td>
            <td>{{ogr.4}}</td>
            <td>{% if ogr.5 %} BAŞARILI
                {% else %}     BAŞARISIZ
                {% endif %}
            </td></tr>
        {% endfor %}
    </table>
</body>
</html>

Artık gerçek anlamda şablonları kullanmaya başladığımıza göre views.py dosyamızdaki görünümümüzü de değiştirmeliyiz.

views.py
# -*- coding: utf-8 -*-

from django.http import *
from django.template import Template, Context



def notlar(request):
    ogrenciler =((u'Kadir',u'Guler',40,85,75,True),
                 (u'Ahmet',u'Baba',22,58,36,False),
                 (u'Suzan',u'Keskin',65,75,95,True),
                 (u'Ufuk',u'Hakan',45,15,36,False),
                 (u'Hayrettin',u'Öğüt',50,69,50,True),
                 (u'Mehmet',u'Kaan',42,85,25,True),
                 (u'Ayşe',u'Sanem',35,90,75,True),
            )
    s=Template(open('C:...\\deneme\deneme\\sablonlar\\notlar.html').read())

    b = Context({'ogrenciler' : ogrenciler})
    html = s.render(b)
    return HttpResponse(html)

Bundan sonra sayfa görünümündeki değişiklikleri yapmak üzere notlar.html üzerinde çalışabiliriz. Bu şekilde yaptığımızda şablon dosyası yok ise, programımız hata verir. Bundan kurtulmak için Django'nun şablon yükleme sistemini kullanabiliriz. Bunun için öncelikle settings.py dosyasındaki TEMPLATE_DIRS değişkenine projemize ait şablonları kaydedeceğimiz klasörü aşağıdaki gibi eklememiz gerekiyor.

TEMPLATE_DIRS = (
          'C:...\\deneme\deneme\\sablonlar' , 
)

Bunu da yaptıktan sonra views.py dosyamıza son halini verebiliriz demektir. Artık sablonun adresini yazmaktan ziyade sadece adını yazmamız yeterli olacaktır.

views.py
# -*- coding: utf-8 -*-

from django.http import *
from django.template import Template, Context
from django.template.loader import get_template



def notlar(request):
    ogrenciler =((u'Kadir',u'Guler',40,85,75,True),
                 (u'Ahmet',u'Baba',22,58,36,False),
                 (u'Suzan',u'Keskin',65,75,95,True),
                 (u'Ufuk',u'Hakan',45,15,36,False),
                 (u'Hayrettin',u'Öğüt',50,69,50,True),
                 (u'Mehmet',u'Kaan',42,85,25,True),
                 (u'Ayşe',u'Sanem',35,90,75,True),
            )
    s=get_template('notlar.html')

    b = Context({'ogrenciler' : ogrenciler})
    html = s.render(b)
    return HttpResponse(html)

Referanslar :
  1. https://docs.djangoproject.com/en/dev/
  2. BAŞER, Mustafa (2013). Django
  3. http://en.wikipedia.org/wiki/IDLE_(Python)
  4. http://docs.python.org/2/tutorial/index.html

1 yorum: