29 Eylül 2008 Pazartesi

Django ile Anket 3

Bundan önceki uygulamarımızda anket oluşturmak, düzenlemek ve yeni seçenekler eklemek gibi bir takım ayarları yapmayı öğrenmiştik. Ama bunları sadece admin paneli üzerinden yapıyorduk. Peki bu anketleri nasıl sayfamızda gösterebiliriz ?

Anketleri sayfamızda gösterebilmemiz için anket uygulaması içerisinde yer alan view.py dosyasında bir takım düzenlemeler yapmamız gerekiyor. View.py dosyasının içeriğini şu hale getirelim.

from django.template import Context, loader
from OrnekProje.anket.models import Anket
from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404

def index(request):
son_anketler = Anket.objects.all().order_by('-yayin_tarihi')[:5]
return render_to_response('anket/index.html',{'son_anketler':son_anketler })

def detail(request, anket_id):
p = get_object_or_404(Anket, pk=anket_id)
return render_to_response('anket/detail.html', {'anket': p})

def all(request):
anketler = Anket.objects.all().order_by('-yayin_tarihi')
return render_to_response('anket/all.html',{'anketler':anketler})

Ardından urls.py dosyanını şu şekilde düzenleyin. Bu arada yukarıda ki kodlar için acele etmeyin hepsini açıklayacağım ;)

urlpatterns = patterns('',
(r'^admin/(.*)', admin.site.root),
(r'^anket/$', 'OrnekProje.anket.views.index'), #[1]
(r'^anket/(?P\d+)/$','OrnekProje.anket.views.detail'),
(r'^anket/all/$','OrnekProje.anket.views.all'),


Öncelikle urls.py dosyasından başlayalım. #[1] ile biten satıra bakalım. Bu satırda djangoya /anket/ adresine gelen bir istek olursa OrnekProje/anket/views dosyasından index fonksiyonun çalıştırılması isteniyor. ( url tanımı yapılırken kullanılan düzenli ifadelerden gökmen ve mirat daha önceki yazılarında bahsettikleri için uzun uzun değinmiyorum.) Şimdi gelelim index fonksiyonuna. İlk satırda son_anketler isimli değişkene veri tabanındaki son 5 anketi tarih sırasına göre atıyoruz. 2. satırda ise render_to_response nesnesini kullanarak
anket dizini içerisindeki index.html dosyanı son_anketler ile verilen değerleri kullanarak bir değer döndürmesini istiyoruz. (Sanki biraz karışık bir cümle oldu :/)

Ama sanki bir şey unuttuk ? anket/index.html diye bir dizin ve dosya yaratmadık. Şimdi OrnekProje dizini içerisinde Templates diye bir dizin oluşturalım. Burada tüm templatelerimizi saklayalım. İyi bir gruplandırma olması açısından her uygulama için ayrı bir dizin kullanalım. Yani onunda içerisinde bir anket dizini oluşturalım.

Bu dizinleri oluşturduktan sonra bunlardan djangoyu haberdar etmeye geldi sıra. Bunun için settings.py dosyasındaki TEMPLATE_DIRS satırını şu şekilde değiştirmemiz gerekiyor.

TEMPLATE_DIRS = ("/home/Deniz/OrnekProje/templates" # dizini kendi dizininizle değiştirmeri unutmayın :)
)


Şimdi tekrar templates/anket klasörüne gidip index.html dosyasını oluşturup içeriğini şu şekilde dolduralım.

{% if son_anketler %}
<ul>
{% for anket in son_anketler %}
<li>{{ anket.soru }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}



İlk satırda ki if sorgusu ile eğer son_anketler değeri var ise aşağıdaki işlemleri yapmasını söylüyoruz.

for döngüsü ise anket olduğu sürece anket sorularını ekrana bastırmamıza yarıyor.

Eğer if sorgusu False değeri döndürürse (yani hiç anket yoksa) else bloğu işletiliyor.

Burada sadece anket sorularını ekrana yazdırdık.

Şimdi urls.py dosyamızın 2. satırını ve detail fonksiyonunu açıklayalım. 2. satırda "/anket/2" "/anket/3" gibi sayfalara gelen isteklerde anket numarasına göre o anketi kullanmamızı için anket_id değerini parametre olarak detail fonksiyonuna gönderiyor.


def detail(request, anket_id):
p = get_object_or_404(Anket, pk=anket_id)
return render_to_response('anket/detail.html', {'anket': p})


Burda da farklı olarak get_object_or_404 nesnesini kullandık. Bu nesne eğer anket_id değeri ile gelen bir değer yoksa ekrana sayfa bulunamadı yazdırmamızı sağlıyor.

Bu da detail.html dosyamızın içeriği

<h1>{{ anket.soru }}</h1>
<ul>
{% for secim in anket.secim_set.all %}
<li>{{ secim.secenek }}</li>
{% endfor %}
</ul>


Burada 3 numaralı anketimizi görüntüledik.

Son fonksiyomuz olan all ve urls.py dosyasındaki ona ait olan satırı uzun uzun anlatmayacağım. Önceki bilgilerimiz ile neyin ne olduğunu anlayabiliriz :) Burada da tüm anketlerimizi ve şıklarını aynı anda sayfaya yazdırıyoruz.

all.html dosyasının içeriği;


{% for anket in anketler %}
<h3> {{anket.soru}} </h3>
{% for secim in anket.secim_set.all %}
<li> {{secim.secenek}} </li>
{% endfor %}
{% endfor %}




Yine template dosyaları aracılığıyla bu yazdıklarımızı özelleştirmek sizin elinizde ;)

12 yorum:

  1. Çok güzel bir yazı olmuş teşekkür ediyorum :)

    Bir problem çıktı. url.py deki (r'^anket/(?P\d+)/$','mysite.anket.views.detail'), satırı şu hatayı veriyor :

    unknown specifier: ?P\

    nedendir?

    YanıtlaSil
  2. hm tamam P harfi fazlaymış :) teşekkürler tekrar.

    YanıtlaSil
  3. slm arkadaslar
    bende ayni hatayi aldim
    unknown specifier: ?P\
    P harfini kaldirdim simdide su hatayi aldim
    unexpected end of pattern
    sebep nedir bilenler varsa yazsin lütfen

    YanıtlaSil
  4. url.py dosyanızı ve almış olduğunuz hatayı tam olarak yapıştırırsanız yardımcı olabiliriz.

    YanıtlaSil
  5. ALDIGIM HATA BU
    error at /
    unknown specifier: ?P\d
    Request Method: GET
    Request URL: http://localhost:8000/
    Exception Type: error
    BUDA URL.PY DOSYASI

    from django.conf.urls.defaults import *
    # Uncomment the next two lines to enable the admin:
    from django.contrib import admin
    admin.autodiscover()
    urlpatterns = patterns('',
    (r'^admin/(.*)', admin.site.root),
    (r'^anket/$', 'OrnekProje.anket.views.index'), #[1]
    (r'^anket/(?P\d+)/$','OrnekProje.anket.views.detail'),
    (r'^anket/all/$','OrnekProje.anket.views.all'),)

    YanıtlaSil
  6. Kodları deneyerek gönderdiğim için bir hata olabileceğine pek ihtimal vermemiştim. Blogger'dan kaynaklı bir hata meydana gelmiş. Linktekine benzer şekilde urls.py dosyanızı değiştirirseniz sorun giderilebilir.
    http://codepad.org/kM6Cn4Wp

    YanıtlaSil
  7. slm deniz kardesim öncelikle tesekkür ederim yardimlarindan dolayi, yazmis oldugun linkden url.py dosyasini degistirdim calismasinda bir sorun yok fakat tek bir anlamadigim sey admin panelinde yazdigim anketler aynen görünüyor fakat seceneklere ne yazarsam yazayim secim object olarak gözüküyor asagidaki ciktiyi direk kopyalayip yapistirdim manage.py syncdb de yaptim bir kac kere yine degismedi sebebi ne ola bilir ?
    hangi marka araba?

    * Secim object
    * Secim object
    * Secim object
    * Secim object

    YanıtlaSil
  8. Şu anda test edemiyorum o yüzden tahmini bir cevap vereceğim. detail.html dosyasında
    {{ secim }}
    bulunan satırda bir eksiklik var gibi duruyor.
    {{secim.secenek}}
    şeklinde değiştirip bir dener misiniz ?

    YanıtlaSil
  9. ok kardesim evet aynen o satirmis yanlis olan düzelttim tamam fakat all.html de ayni sorun varmis onuda su sekil degistirdim senden ilham alarak tabi
    1-ikinci satirdaki anketi anket.soru olarak
    2-ücüncü satirdaki for secenek in anket vs secenegi secim olarak
    3-son olarak dördüncü satiri secim.secenek olarak degistirdim hic sorun kalmadi
    ilk defa calistira bildigim bir django kodu oldu
    sagol kardesim hersey icin teskr.
    ayrica all.html icerigi asagidaki adreste
    http://codepad.org/TSNOa8V5

    YanıtlaSil
  10. Yazıyı verdiğin içeriği de düzenleyerek güncelledim.
    Teşekkürler.

    YanıtlaSil
  11. Slm arkadaslar
    Diyelimki django ile güzel bir site olusturduk
    yayinlamak istiyoruz hangi asamalardan gecmemiz lazim bir yerde okumustum sunucunun pythonu desteklemesi gerekiyormus falan bu konuda asci arkadaslardan rica ediyorum bilgilerini bizimle
    paylassinlar
    Google app enginede django kodlarini test edebilirmiyiz
    bilgilerini bizimle paylasan kisilere simdiden tesekkürler

    YanıtlaSil
  12. dediğiniz herşeyi yaptım ama şu hatayı veriyor neden?
    ImproperlyConfigured at /
    Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.

    YanıtlaSil