25 Nisan 2014 Cuma

Sayfalama

Web sayfalarında veri çekilirken tüm verilerin bir anda çekilerek yüklenmediğini fark etmişsinizdir. Belli sayıda veri çekilerek kullanıcıya gösterilir.Kullanıcının istemesi durumunda aynı şekilde tekrardan veriler veritabanından çekilerek kullanıcıya gösterilmeye devam edilir. Bu şekilde yapılmasının nedeni nedir? Çok fazla sayıda verinin tutulduğu bir veritabanı düşünürsek, verilerin bir anda çekilmesi veritabanına çok yük bindirir. Bu da sistemin yavaş çalışmasını sebep olur. Bunun yanında çok fazla verilerin aynı sayfada yüklenmesi göze de hoş gelmez. Bu tarz kötü durumlardan kaçınmak için sayfalama yapısı kullanılır.
Google'ın Sayfalaması
Google'da arama yaptığınız da milyonlarca sonuç bulunur. Hepsinin aynı sayfa üzerinde göründüğünü düşünsenize!
Django Sayfalama Yapısı
Django her şeyde olduğu gibi sayfalama yaparken de bize çok kolaylıklar sağlıyor. Django'nun sayfalamasını anlayabilmek için ilk önce kabuk üzerinde özelliklerine bakalım. Kabuğu nasıl açacağımızı biliyoruz.
python manage.py shell
İlk önce sayfalamanın Paginotor nesnesini içe aktaralım.
>>>from django.core.paginator import Paginator
Bir liste oluşturalım ve bu liste üzerinden sayfalamadan bahsedelim.
>>>universiteler = ['Sakarya','İstanbul','Bogozici','Hacettepe','Ege','Ankara']
Listeyi ve her sayfada kaç eleman olacağını Paginator işlevine parametre olarak gönderiyoruz.
>>>sayfalar = Paginator(universiteler,3)
Eleman sayısı;
>>> sayfalar.count
6
Sayfa sayısı;
>>> sayfalar.num_pages
2
Sayfa aralığı;
>>> sayfalar.page_range
[1, 2]
Sayfaları almak;
>>> sayfa1 = sayfalar.page(1)
>>> sayfa1
<Page 1 of 2>
>>> sayfa2 = sayfalar.page(2)
>>> sayfa2
<Page 2 of 2>
Olmayan bir sayfayı almaya çalışırsanız, hata ile karşılaşırsınız. Sayfa numaraları 0'dan değil 1'den başlar.
>>> sayfa3 = sayfalar.page(3)
Traceback (most recent call last):
...
>>>> sayfa3 = sayfalar.page(0)
Traceback (most recent call last):
...
Aldığımız sayfalardaki elemanlar;
>>> sayfa1.object_list
['Sakarya', '\xc4\xb0stanbul', 'Bogozici']
>>> sayfa2.object_list
['Hacettepe', 'Ege', 'Ankara']
Türkçe karakter sorununa takılmayın. Tarayıcı da bu problemleri almayacağız.
Sonraki sayfa var mı?
>>> sayfa1.has_next()
True
>>> sayfa2.has_next()
False
Önceki sayfa var mı?
>>> sayfa2.has_previous()
True
>>> sayfa1.has_previous()
False
Başka sayfalar var mı?
>>> sayfa2.has_other_pages()
True
Sayfadaki ilk ve son elemanın indisi;
>>> sayfa2.start_index()
4
>>> sayfa2.end_index()
6
Sayfa numarası
>>> sayfa2.number
2
Sayfalamanın Görünümler ile Kullanılması
Şimdi gelelim asıl konumuza. Doktorlar listesini sayfalama yaparak gösterelim. İlk önce Doktor_listesi görünümünü düzenleyelim.
from django.core.paginator import Paginator
def Doktor_listesi(request):
 siralama = 'adi'
 kiriter = request.GET.get('siralama')
 sayfa = request.GET.get('sayfa',1)
 if kiriter:
  siralamaKriteleri = {
   '1':'adi',
   '2':'soyadi'
  }
  if kiriter in siralamaKriteleri:
   siralama = siralamaKriteleri[kiriter]

 doktorlar_tum = Doktor.objects.order_by(siralama)
 doktorlar_sayfalari = Paginator(doktorlar_tum,5)
 doktorlar = doktorlar_sayfalari.page(int(sayfa))
 return render_to_response('doktor_listesi.html',locals())
Paginator işlevini içe dahil etmeyi unutmayın. Her sayfada 5 doktor göstereceğimiz şekilde düzenleme yaptık. sayfa değişkenini GET metodu ile aldığımıza dikkat edin. Eğer bir değer atanmamışsa varsayılan olarak 1 olacaktır. Şablonu da yeniden düzenleyelim.
<table border="1">
    <tr><td><a href="/doktor-ekle/">Doktor Ekle</a></td></tr>
    <tr>
        <th>Sıra</th>
        <th><a href="?siralama=1">Adi<a/></th>
        <th><a href="?siralama=2">Soyadi</a></th>
        <th>Telefon</th>
        <th>E-Posta</th>
        <th>İşlemler</th>
    </tr>

    {% for doktor in doktorlar %}
    <tr>
        <td>{{ doktorlar.start_index|add:forloop.counter }}</td>
        <td>{{ doktor.adi }}</td>
        <td>{{ doktor.soyadi }}</td>
        <td>{{ doktor.telefon }}</td>
        <td>{{ doktor.eposta }}</td>
        <td><a href="/doktor-ekle/?id={{ doktor.id }}">Düzenle</a><a href="/doktor-sil/?id={{ doktor.id }}">Sil</a></td>
    </tr>
    {% endfor %}

</table>

{% if doktorlar.has_previous %}
    <a href="?sayfa={{ doktorlar.previous_page_number }}">Önceki</a>
{% endif %}

{{ doktorlar.number }}

{% if doktorlar.has_next %}
    <a href="?sayfa={{doktorlar.next_page_number }}">Sonraki</a> 
{% endif %}
Artık doktorlar listesinin görünümü aşağıdaki gibi olacaktır. Tam da istediğimiz gibi değil mi ? Django bizim için her şeyi halletti.
Google'ınki gibi bir sayfalama yapmak isterseniz şablonda eklediklerimizi silerek şu satırı ekleyebilirsiniz.
{% for i in doktorlar.paginator.page_range %}
    {% if doktorlar.number == i %}
    <a href="?sayfa={{i}}" class="secili">
    {% else %}
    <a href="?sayfa={{i}}">
    {% endif %}
        {{i}}</a>
{% endfor %}
Burada secili class'ı o anda bulunulan sayfanın numarasına atanmıştır. Bunu kullanarak stil verebiliriz. Bu şekilde kullanıcı hangi sayfada olduğunu rahatça anlayabilir.
Kaynakça

0 yorum :

Yorum Gönder