30 Ekim 2008 Perşembe

Google App Engine uygulama geliştirme 2

Google App Engine ile uygulama geliştirmenin ikinci sayısında aslında sizlere apilerden bahsedecektim ama farklı konulardan bahsedeceğim. Bunlar;

1. Google App Engine Django Kurulumu
2. Google App Engine ve Django Form Yaratma
3. Formları İşleme Ziyaretçi Defteri Uygulaması

Hiç laf ebeliği yapmadan olaya giriyorum çünkü uzun bir yazı olacak.

1. Google App Engine Django Kurulumu:
Öncelikle şunu söylemeliyim, Appengine'nin kendi web çatısı var ancak, dökümasyonu djangonun çok iyi ve sadece dökümasyon ile sınırlayamam artılarını. Bir kaç sebebden olsa gerek ısrarla django ile çalışıyorum appenginede. Şimdi sıra sıra nasıl Google'ın beleş uygulama motorunda çalışacağını görelim.

a) django-admin.py startproject yetis şeklinde bir proje başlattık. Ayrıntılara takılmayın isimler saçma bende profesyonel kodcu değilim :D

b) main.py

c) settings.py

d) app.yaml

application: app_engine_domain_adi
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
script: main.py

app.yaml dosyası hakkında daha önce neyin ne olduğunu anlatmıştım ve linklerde vermiştim bu sebebden dolayı bir daha üzerinden geçmiyeceğim. Şimdi bir deneme yapın ekranda django falan diyecek :D google_appengine/dev_appserver.py dosyanin_bulundugu_yer

e) Artık bir uygulama başlata biliriz ortam uygun hale geldi :D
> cd yetis
> python manage.py startapp Blog
uygulamamızın adı Blog olsun...

Artık Django'yu Google App Engine'de kullanabilirsiniz.

2. Google App Engine ve Django Form Yaratma ve İşleme:
Bu konudan açarak bahsetmek istiyorum bu nedenle link vermiyeceğim. Django Form işleme,yaratma,düzenlemenin Appengine'ye uyarlamasıdır, yani bu uygulama Django içindir Appengine sadece çalıştırır :D

Karışıklığı önlemek için dosya yapısının tree'sini veriyorum.
|----- app.yaml
|----- index.yaml
|----- main.py
`----- yetis
------|----- Blog
------|----|----- bform.py
------|----|----- models.py
------|----|----- templates
------|--------------- ziyaretci.html
------|--------- views.py
------|----- manage.py
------|----- settings.py
------------ urls.py

Django ile proje başlattık ( yetis ) ve birde uygulama açtık ( Blog ) . Şimdi sıra ile gidelim
a) Model oluşturulacak
b) Model için Form oluşturulacak

a) Model Oluşturulacak:
Modelimizi bir ziyaretçi defteri oluşturma uygulamasına göre oluşturuyorum.

from google.appengine.ext import db
class Z_Defteri(db.Model):
ad = db.StringProperty(verbose_name="Ad",required=True)
soyad = db.StringProperty(verbose_name="Soyad",required=True)
not_ = db.TextProperty(verbose_name="Mesaj")
inci = db.IntegerProperty(default = 0)
tarih = db.DateTimeProperty(auto_now_add = 1)
yazan = db.UserProperty()

def __unicode__(self):
return "%s %s %s %s"%(self.not_,self.ad,self.soyad,self.inci)

Modeldeki alanların parantezleri içindeki değişkenlerden bahsedelim.
verbose_name = "Ad" ----> Tablom oluştuğunda alanın ismini "Ad" yaptım. Yani şurası; <input type="text" name="ad" id="id_ad"
Peki neden bunu yaptık. Tabloya müdahale gücümüzü arttırmak için. Biz isim vermezsek kendisi uygun bir isim atıyacaktı zaten. Bunu neden biz yapmayalım :D
required = True ----> Bu özellik bizi zahmetten kurtarıyor. Şimdi bu alan gerekli mi_? gereksiz mi_? bir diğer değişle, bu alan hiç girilmesede olur mu? Bunu belirlemek için şöye dedik : luzumlu = Evet işte bunu söylüyoruz. Peki neden! Hata takibi yapmak için, eğer kullanıcı benım oluşturduğum bir tablonun alanını es geçerse ben ona hopbala, burayı doldurmadan geçiş izni yok diyorum :)
default = 0 ---> Ön tanımlı olarak sıfır değerini alsın.
auto_now_add = 1 ---> Tarihi commit yaptığımda otomatik oluştur.


b) Model için Form oluşturulacak:
Nedir! Ne değildir! Model için Form derken Modelin alanları için işlem yapabileceğim bir form alanı oluşturmakdan bahsediyoruz. Bunu el ile de yapabilirsiniz ama neden yapasınız! Bir sürü koddan ve hata takibinden kurtuluyorsunuz. Başlayalım! Öncelikle bform.py adında bir dosya oluşturalım. Dosyanın nerede oluştuğunu yukardaki tree'e bakarak görebilirsiniz.
bform.py

from models import Z_Defteri
from google.appengine.ext.db import djangoforms

class ZD_Form(djangoforms.ModelForm):
class Meta:
model = Z_Defteri
fields = ('ad','soyad','not_','tarih',)
exclude = ['inci','yazan']

----> "from models import Z_Defteri" ile modelimizin aldık
----> "from google.appengine.ext.db import djangoforms" Appengine'nin django'da bulunan ModelForm olayını kullanmamızı sağlayan modulunu aldık.
----> ZD_Form sınıfımıza djangoforms.ModelForm miras atadık. Buradaki ModelForm django'da 1.0 da var. Önceki versiyonunda yok 0,96 da NewForm olsa gerek :D
Öntanımlı değişkenlerden bahsedeyim.
-----> model = Z_Defteri burada modelimizdeki değişkenleri atadık
-----> fields = ('ad','soyad','not_','tarih',) kullanacağımız alanlar
-----> exclude = ['inci','yazan'] ilk form oluştuğunda form'da gözükmesini istemediğimiz alanlar.

bform.py dosyasının içine bu uygulamada kullanacağınız butun formları atabilirsiniz. Böylelikle herşey toparlı olmuş olur.
3. Formları İşleme Ziyaretçi Defteri Uygulaması
İstediğimiz model için istediğimiz formu oluşturduk. Şimdi bu oluşturduğumuz formu ekranda göstermek ve kayıt, düzenleme, silme gibi uygulamaları yapmak kaldı. Burada sadece kayıt olayını ele alacağım. Ziyaretçi defteri uygulaması örneği üzerinde form işlemeyi göreceksiniz!

Bunun için üzerinde değişiklik yapacağım dosyalar. template klasöründeki ziyaretci.html dosyası, Blog uygulamasındaki views.py ve yetis projesindeki urls.py dosyalarıdır. Yukardaki tree'ye göre dosyaların yerlerini tesbit edebilirsiniz.
Öncelikle views.py dosyası:

from django.http import HttpResponse, HttpResponseRedirect
from yetis.Blog.models import Z_Defteri
from bform import ZD_Form
from django.shortcuts import render_to_response
from google.appengine.ext import db
from google.appengine.api import users

Formları oluşturduğumuz yer bform.py den ZD_Form'u çektik, users,db apilerini ekledik, djangonun bir kaç fonksiyonunu ekledik.

def ziyaretci_defteri(request):
yazilanlar = Z_Defteri.all()
yazilanlar.order("-tarih")
yazilanlar = yazilanlar.fetch(10)

kullanici = users.get_current_user()
ndform=''
if kullanici:
k_islem = ("Hosgeldiniz, %s! (<a href=\"%s\">Cikis Yap</a>)" %(kullanici.nickname(), users.create_logout_url("/")))

if request.method == "POST":
zdform = ZD_Form(request.POST)
if ndform.is_valid():
yazan = kullanici
inc =Z_Defteri.all()
inci = inc.count()
not_ = (request.POST["not_"]).decode("utf8")
ad = (request.POST["ad"]).decode("utf8")
soyad = (request.POST["soyad"]).decode("utf8")
kayit = Z_Defteri(not_=not_,ad=ad,soyad=soyad,inci=inci,yazan=yazan)
kayit.put()
return HttpResponseRedirect('/')
else:
zdform = ZD_Form()

else:
k_islem = ("<a href=\"%s\">Giris Yapiniz</a>." % users.create_login_url("/"))

return render_to_response('ziyaretci.html',{'zdform':zdform,'yazilanlar':yazilanlar,'k_islem':k_islem,'kullanici':kullanici} )

Algoritması!
--->Önce sayfaya giren kişinin google kullanıcısı olup olmadığına bakıyoruz,
-------> google kullanıcısı ise ziyaretçi defterine not bırakmasına izin veriyoruz
-------------> Eğer Post ediliyor ve mothodumuz POST ise Form oluştur
-------------------->submit tuşuna basılmış ve Form boş bırakılmamışsa
-------------------------->Veritabanına Formda girilen alanları yaz.
-------------> Post edilmemiş ise sadece Form oluştur
--->değil ise google giriş sayfasına yönlendiriyoruz giriş yapıp tekrar yönlendirilsin.
Değişkenleri anlatacağım;
yazilanlar --> Ziyaretçi defterine yazılan yazının argümanlarının tamamını sorgu ile çekiyor.
kullanici --> Sayfayı ziyaret eden kişi. Dilerse deftere birşeyler yazabilir.
k_islem --> kullanici işemleri. Giriş ve Çıkış işlemi sadece :D
zdform --> Ziyaretçi Defteri form bilgilerini bu değişken ile alıyoruz. Form bu değişkende oluşuyor.

Burada daha fazla derine inmiyeceğim. Django'dan anlıyan arkadaşlar anlamışlardır diye umut ediyorum. Appengine kullanan arkadaşlar ise yeterince açıklayıcı olduğumu düşünüyorum.Sıra tempaltes kısmına geldi. Web sayfasında göstermek ve güzel görüntü oluşturmak için template kullanıyoruz.
Blog uygulaması içine bir templates klasörü açın ve içine ziyaretci.html dosyası açın. İçeriğinin bir kısmını bilgi amaçlı olarak burada, geri kalan tamamının linkini vereceğim.
en üstte {{k_islem}} koyarak kullanıcının gmail kullanıcı olup olmadığına bakarak yönlendirebiliriz.

<form action="." method="post">
<table>
{{zdform}}
</table>
<table>
<input type="submit" name="gonder" value="Gönder" class="inputsag"/>
</table>
</form>

Formumuz bu şekilde ekranda gözüktü :D zdform.as_b derseniz "b" halinde zdform.as_ul "ul" şeklinde zdform.as_table ise "table" şeklinde form oluşturur. Hiç birşey yapmazsanız sadece form oluşur.


{% for not in yazilanlar %}
<table>
<TD>
<p id="kisi">{{not.ad}} {{not.soyad}} <hr>
<em> id="eposta">{{not.yazan.email}}</em>
<em id="tarih">{{not.tarih|date:"d M Y D"}}</em></p>
<p> id="mesaj">{{not.not_}}</p>
</table>
</TD>
{% endfor %}

burada appengine ait olan yer "not.yazan.email" kısmıdır. Kullanıcının email adresini yazdırıyorum."not.tarih|date:"d M Y D"" burada ise tarihi filitre ederek ekrana basıyorum.
html dosyasının kod kısmı buradan ibarettir.

Çalışır halini görmek için

http://pythonizm.appspot.com



referanslar:
1- http://code.google.com/appengine/docs/datastore/creatinggettinganddeletingdata.html
2- http://appengineguy.com/2008/06/proper-unit-testing-of-app-enginedjango.html
3- http://www.djangobook.com/en/1.0/chapter07/
4- http://docs.djangoproject.com/en/dev/ref/forms/fields/
5- http://code.google.com/appengine/articles/django.html

1 yorum:

  1. Bir ornekte bizden.

    http://www.mutlusms.com

    API'mizi inceleyin

    YanıtlaSil