Python Web çerçeveleri, Bölüm 2: TurboGears ve Python ile Web geliştirmesi
Çevrimiçi bir alışveriş uygulaması temel özellikleri gösterir
Düzey: Orta
Ian Maurer (ian@itmaurer.com),
Üst Düzey Danışman, Brulant, Inc.
11 Temmuz 2006
İki bölümlük dizinin bu ikinci makalesinde, Python'a dayalı olan açık kaynak MVC biçimindeki bir Web uygulaması çerçevesi olan TurboGears'i tanıtacağız. İlk makale Django çerçevesine giriş olarak yazılmıştır; bu makalede ise Web tabanlı bir alışveriş uygulaması yaratmak için TurboGears'ı nasıl kullanacağınız anlatılır ve sonunda Turbogears ile Django birbiriyle karşılaştırılır.
TurboGears geliştiricileri bu projeyi bir "mega çerçeve" olarak adlandırır, çünkü bu daha önce var olan çeşitli alt projelerden oluşur. TurboGears birkaç ana bileşenin biraraya getirilmesine yardımcı olur:
- MochiKit: JavaScript kitaplığı
- Kid: Şablon oluşturma dili
- CherryPy: Temel Web çerçevesi
- SQLObject: Nesne ile ilişkisel eşleyici (ORM)
TurboGears ile çalışmanın ilk adımı, Python'un mutlaka kurulu olduğundan emin olmaktır. TurboGears'ın en son sürümü için Python 2.4 gereklidir. Python ana sayfası bağlantısı için, Kaynaklar bölümüne bakın.
Python topluluğunun sunduğu yeni bir proje olan Setuptools (kuruluş araçları), Python yazılımının kurulmasını ve güncellenmesini oldukça kolaylaştırır. Yazılım, Egg olarak adlandırılan ve bir Java™ JAR dosyasına ya da bir Ruby GEM dosyasına benzeyen bir arşiv dosyasında bulunur, easy_install adı verilen bir araç tarafından yüklenir ve kurulur.
TurboGears, dağıtım ve kuruluş için Setuptools'u kullanan ilk büyük Python projelerinden biridir. Setuptools sayfasına ve Turbogears yükleme sayfasına bağlantı için Kaynaklar bölümüne bakın.
Bu makalede, makalenin yazıldığı sırada en son geliştirme sürümü (0.9a5) kullanılmıştır ve bu sürüm önizleme yükleme sayfasından alınabilir:
easy_install -f
http://www.turbogears.org/preview/download/index.html TurboGears
TurboGears'ın en son sabit sürümünü (0.8.9 geçerli) almak için tek yapmanız gereken, -f
seçeneğini ve önizleme sitesi URL'sini kaldırmaktır:
easy_install TurboGears
TurboGears admin (yönetim) aracının denetlenmesi
TurboGears'ı kurduktan sonra, yolunuz üzerinde tg-admin
adlı admin (yönetim) aracınızın bulunması gerekir. Komut satırında tg-admin
yazarak bunu denetleyin:
Liste 1. TurboGears yönetim aracının kullanılması
~/dev$ tg-admin TurboGears 0.9a5 command line interface Usage: /usr/bin/tg-admin [command] [options] Available commands: i18n Manage i18n data info Show version info quickstart Create a new TurboGears project shell Start a Python prompt with your database available sql Run the SQLObject manager toolbox Launch the TurboGears Toolbox update Update an existing turbogears project |
Bir TurboGears projesine başlamak için, tg-admin quickstart
işlevini kullanın. Başlarken sizden hem bir proje adı, hem de bir dizin adı sağlamanız istenir. Bu makale için, paket adı tgcommerce
olan TG Commerce
adlı basit bir alışveriş sepeti örneği yarattım:
Liste 2. Bir TurboGears projesine başlama
~/dev$ tg-admin quickstart Enter project name: TG Commerce Enter package name [tgcommerce]: Selected and implied templates: turbogears#turbogears web framework Variables: package: tgcommerce project: TG-Commerce Creating template turbogears Creating ./TG-Commerce/ ... (output snipped) ... |
TurboGears, altında tgcommerce paketi olan bir TG-Commerce proje dizini yaratır. Artık projenizle birlikte gelen test sunucunuzu çalıştırabilirsiniz:
Liste 3. Test sunucusunun başlatılması
~/dev/TG-Commerce$ python start-tgcommerce.py ... (output snipped) ... 05/Mar/2006:11:31:54 HTTP INFO Serving HTTP on http://localhost:8080/ |
Sağlanan URL'deki test sayfasını gözden geçirin, daha sonra Ctrl-C tuşlarını kullanarak sunucuyu sonlandırın.
SQLObject, veritabanı bazında tutarlı Python nesneleri geliştirmenizi sağlayan bir nesne ile ilişkisel eşleyici (ORM) kitaplığıdır. Burada bir Python sınıfı tanımlarsınız, istenen öznitelikleri (alanları) eklersiniz; sonra tablo yaratmak, yeni kayıt eklemek, var olan kayıtları bulmak, güncellemek ya da silmek için gereken SQL oluşturma işlemini SQLObject yönetir.
SQLObject, MySQL, PostgreSQL, Firebird ve diğerlerini de içeren çeşitli veritabanlarını destekler. Kaynaklar bölümündeki bağlantıyı tıklatarak SQLObject'e ilişkin daha fazla bilgi edinebilirsiniz.
Bu örnekte, veritabanı arka ucu olarak SQLite kullanılmıştır. SQLite, hiçbir yapılandırma gerektirmeyen ve diskte basit bir dosya olarak yer alan basit bir veritabanıdır. SQLite'ı kullanmak için, setuptools yoluyla pysqlite kitaplığını kurun:
easy_install pysqlite
TurboGears veritabanını yapılandırmak için, dev.cfg dosyasında sqlobject.dburi
komutunu yazın. SQLite için, veritabanı dosyasının yer almasını istediğiniz yolu belirtin:
Liste 4. Geliştirme yapılandırma dosyası (dev.cfg)
sqlobject.dburi="notrans_sqlite:///path/to/devdir/TG-Commerce/tgcommerce.database" server.environment="development" autoreload.package="tgcommerce" |
TurboGears quickstart, model.py dosyasını yaratır ve önceden içine bir ortak kod yerleştirir. Burası, SQLObject sınıflarının yerleştirilmesi gereken yerdir. Üstte, veritabanı bağlantısı göbeğini (hub) oluşturan bölüm vardır:
Liste 5. Model ortak kodu (model.py)
from sqlobject import * from turbogears.database import PackageHub hub = PackageHub("tgcommerce") __connection__ = hub |
Daha sonra sıra, model sınıflarına gelir. Her biri, veritabanında,
veritabanı sütunlarıyla eşleşen sınıf düzeyi öznitelikleriyle
tanımlanan bir tabloyu temsil eder. Bu öznitelikler, StringCol
ve CurrencyCol
gibi temel veri tipleriyle, ForeignKey
ve MultipleJoin
gibi ilişki tiplerini içeren SQLObject sütun tiplerinin eşgörünümleridir.
Bu alışveriş sepeti, hiyerarşik bir Category
(Kategori) ve basit bir Product
(Ürün) sınıfı içermektedir. Kategori hiyerarşisi, ana ForeignKey
öğesi ve alt kategoriler MultipleJoin
tarafından tanımlanır.
Liste 6. Kategori ve Ürün sınıfları (model.py, devam)
class Category(SQLObject): name = StringCol(length=64) parent = ForeignKey('Category', default=None) subcategories = MultipleJoin('Category', joinColumn='parent_id') products = MultipleJoin('Product') class Product(SQLObject): name = StringCol(length=64) sku = StringCol(length=64) price = CurrencyCol(notNone=True, default=0.0) category = ForeignKey('Category') |
Modeli doğrulamak için, gereksinim duyulan tabloları yaratacak olan SQL kodunu görüntülemek üzere tg-admin sql sql
komutunu kullanın.
SQLObject'in her bir tablo için bir id
(tanıtıcı) sütunu yarattığına dikkat edin. Bu durum, hiçbir birincil anahtar tanımlanmadığında oluşur. SQLObject hakkındaki belgelere ve bağlantılara ulaşmak için, Kaynaklar başlıklı bölüme bakın.
Liste 7. 'tg-admin sql sql' komutunu kullanarak veritabanı şemasının görüntülenmesi
~/dev/TG-Commerce$ tg-admin sql sql Using database URI sqlite:///home/ubuntu/dev/TG-Commerce/tgcommerce.db CREATE TABLE category ( id INTEGER PRIMARY KEY, name VARCHAR(64), parent_id INT ); CREATE TABLE product ( id INTEGER PRIMARY KEY, name VARCHAR(64), sku VARCHAR(64), price DECIMAL(10, 2) NOT NULL, category_id INT ); |
Aşağıda, alışveriş sepetini ve bunun içindeki kalemleri saklamak için kullanılan Order
(Sipariş) ve OrderItem
(Sipariş Kalemi) sınıfları görülmektedir.
order bir SQL anahtar sözcüğü olduğu için, Order
sınıfına ilişkin tablo adı, sqlmeta
altsınıfının tablo öznitelikleri kullanılarak orders
'ta yeniden tanımlanır:
Liste 8. Order (Sipariş) ve OrderItem (Sipariş Kalemi) sınıfları (model.py, devam)
class Order(SQLObject): items = MultipleJoin('OrderItem', joinColumn='order_id') class sqlmeta: table = 'orders' class OrderItem(SQLObject): quantity = IntCol(notNone=True) price = CurrencyCol(notNone=True) total = CurrencyCol(notNone=True) order = ForeignKey('Order') product = ForeignKey('Product') |
Veritabanı tablolarını yaratmak için tg-admin sql create
komutunu kullanın:
Liste 9. 'tg-admin sql create' komutunu kullanarak veritabanı tablolarının yaratılması
~/dev$ tg-admin sql create Using database URI sqlite:///home/ubuntu/dev/TG-Commerce/tgcommerce.db |
tg-admin sql help
komutunu kullanarak, tabloları bırakma komutu da dahil olmak üzere pek çok komut bulabilirsiniz. Bu komutu kullanırken çok dikkatli olun, çünkü bu komut, içerdikleri verilerle birlikte tüm tablolarınızı da siler.
Yalnızca bu nedenle bile, tg-admin
komutunun üretim ortamında kilitlenmesi gerekir.
Modelin CatWalk ile kullanılması
TurboGears, sürüm 0.9'dan başlayarak, Toolbox adı verilen ve CatWalk aldı bir model tarayıcısını içeren bir araç takımıyla birlikte sağlanır. CatWalk, bir GUI aracı kullanarak modelleri için hızlı bir biçimde veri yaratmak, güncellemek ve silmek isteyen geliştiricilere yönelik olarak tasarlanmıştır.
Toolbox (araç kutusu) ayrı bir sunucu olarak başlatılır ve tg-admin
komutu kullanılarak çalıştırılır:
Liste 10. tg-admin komutunu kullanarak Toolbox sunucusunun başlatılması
~/dev/TG-Commerce$ tg-admin toolbox ... (snip) ... 05/Mar/2006:15:01:33 HTTP INFO Serving HTTP on http://localhost:7654/ |
Bir tarayıcı otomatik olarak açılmazsa, Toolbox sunucusu tarafından belirtilen URL adresine (http://localhost:7654/) gidin ve CatWalk aracını açmak için CatWalk bağlantısını tıklatın.
Şekil 1. CatWalk aracı
Toolbox, son kullanıcılara değil geliştiricilere yönelik olarak geliştirilmiştir ve veri modellemesine ve uygulamalarınıza veri önyüklemesi yapılmasına yardımcı olmak amacıyla kullanılır. Toolbox sunucusunu Ctrl-C tuşlarını kullanarak kapatabilirsiniz. Bunu bu gözden geçirme çalışmasında kullanmayacaksınız.
TurboGears'ta görünüm yaratmak için varsayılan yol, Kid adlı XML şablon oluşturma dilinin kullanılmasıdır. Kid, XML'i kullandığı için, tüm şablonların düzgün bir biçimde oluşturulması gerekir, tersi durumda, oluşturma sırasında olağandışı bir durum ortaya çıkar. Kid ayrıca, ortak kodun tek bir yerde yaratılabilmesi ve buna bakım yapılabilmesi için türetilmiş şablonların temel şablonlardan genişletilebildiği template inheritance olanağını da destekler.
TurboGears'ta, Kid dosyaları şablonlar dizininde .kid uzantısıyla yer alır. Varsayılan değer olarak, bir master.kid dosyası ve bir welcome.kid dosyası bulunur; master.kid temel şablon dosyasıdır ve welcome.kid <html> etiketindeki py:extends
özniteliğini kullanarak bundan devralır.
Yeni bir şablon yaratmak için, welcome.kid dosyasını kopyalamanızı ya da yeniden adlandırmanızı ve başlangıç noktanız olarak bunu kullanmanızı öneririm. Kategori şablonu ilk başta bu örnek için yaratılmıştı; verilen bir kategoriye ilişkin aşağıdaki bilgileri gösterir:
- Kategori adı (başlık)
- Önceki öğelere (ancestor) olan bağlantılar ("breadcrumbs")
- Alt kategorilere olan bağlantılar (liste)
- Ürünlere olan bağlantılar (liste)
Liste 11. Kategori sınıfı kid şablon dosyası (category.kid)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" py:extends="master.kid"> <head> <title>Category: ${category.name}</title> </head> <body> <div id="breadcrumbs"> <ul> <li py:for="ancestor in list(category.ancestors)[::-1]"> > <a href="/category/${ancestor.id}" py:content="ancestor.name"></a> </li> <li id="active"> > <span py:replace="category.name" /> </li> </ul> </div> <div id="subcategories" py:if="category.subcategories"> <div class="header">Subcategories</div> <ul> <li py:for="subcategory in category.subcategories"> <a href="/category/${subcategory.id}" py:content="subcategory.name"></a> </li> </ul> </div> <div id="subcategories" py:if="category.products"> <div class="header">Products</div> <ul> <li py:for="product in category.products"> <a href="/product/${product.id}" py:content="product.name"></a> </li> </ul> </div> </body> </html> |
Liste 11'de anahtar Kid işlevlerinden bazıları gösterilmiştir:
-
py:extends
kullanılarak master.kid dosyasından devralma -
${category.name}
kullanılarak başlıktaki anlatımı değiştirme -
py:for
kullanılarak önceki öğe (ancestor), altsınıflar ve döngüler arasında döngü gerçekleştirme - Breadcrumbs'taki önceki öğe (ancestor) görünümünü tersine çevirmek için dilimleme mantığını kullanma
-
py:content
kullanılarak bir bağlantıdaki metni doldurma -
py:replace
kullanılarak bir yayılma etiketini değiştirme
Yukarıda sözü edilen ancestors
(önceki öğeler) özniteliğinin geçerli olması için, Category model sınıfının bir _get_ancestors
yöntemi içerecek biçimde değiştirilmesi gerekir:
Liste 12. Category sınıfına 'ancestors' özniteliği 'get' yöntemi eklenmesi
class Category(SQLObject): name = StringCol(length=64) parent = ForeignKey('Category', default=None) subcategories = MultipleJoin('Category', joinColumn='parent_id') products = MultipleJoin('Product') def _get_ancestors(self): ancestor = self.parent while ancestor: yield ancestor ancestor = ancestor.parent |
TurboGears quickstart, Root
(Kök) denetleyici
sınıfının yeri olan controllers.py
modülüne sahip bir proje
sağlar. Bu, uygulamanız için ana giriş noktasıdır ve yeni denetleyici yöntemlerinin ekleneceği yerdir.
TurboGears expose
dekoratörü sayesinde kategori HTML şablonlarıyla ilişkili olan iki örnek denetleyici yöntemi aşağıda gösterilmiştir. Denetleyici yöntemleri, belirtilen Kid şablonunun oluşturulması sırasında ad boşluğu ya da içerik olarak kullanılan sözlükleri döndürür.
Liste 13. Controller (denetleyici) sınıfı
from turbogears import controllers, expose class Root(controllers.Root): @expose("tgcommerce.templates.category") def index(self): from model import Category category = Category.selectBy(parent=None)[0] return dict(category=category) @expose("tgcommerce.templates.category") def category(self, categoryID): from model import Category category = Category.get(categoryID) return dict(category=category) |
TurboGears'ta, URL'ler yöntemlerle sorunsuz bir biçimde eşleşir ve Root
(Kök) denetleyici içerisinde yer alır. Kök URL /
, index
adı verilen özel bir yöntemle eşleşir.
Root
'a category
adlı bir yöntem ekleyerek, /category
URL'si yoluyla buna erişilebilir.
Bir default
(varsayılan) yöntem tanımlı değilse, verilen bir yöntemle eşleşmeyen herhangi bir URL'nin sunulması 404 hatasına neden olur.
Aşağıda bazı olası URL senaryoları ve bunların sonuçları gösterilmiştir:
/
: üst tanıtıcı olmadan ilk kategoriyi gösterir/category?categoryID=2
: 2 tanıtıcısına sahip kategoriyi gösterir./category/1
: 1 tanıtıcısına sahip kategoriyi gösterir (bu biçim TG 0.9 ile sağlanmıştır)/category
: kategori tanıtıcısı olmadığı için bir 500 hatası gönderir./xyz
: bir 404 hatası gönderir
Şekil 2 kategori görüntüleme sayfasını gösterir:
Şekil 2. Kategori görüntülenmesi
Ürün görüntüleme sayfası için, bir ürünü veritabanından alıp oluşturmak üzere bunu product
Kid şablonuna geçiren bir product
denetleyicisi yaratılır.
Liste 14. Ürün denetleyicisi yöntemi eklenmesi
@expose("tgcommerce.templates.product") def product(self, productID): from model import Product product = Product.get(productID) return dict(product=product) |
product.kid şablonunda ürün bilgileri tablosu bulunur. İki önemli basamağı olan bir fiyatı görüntülemek için Python dize biçimlendirmesinin kullanımına dikkat edin:
Liste 15. Kategori sayfası kid şablonu dosyası (product.kid)
<table id="product-info"> <tr> <td class="fld">Name:</td> <td class="val"><span py:replace="product.name" /></td> </tr> <tr> <td class="fld">SKU:</td> <td class="val"><span py:replace="product.sku" /></td> </tr> <tr> <td class="fld">Price:</td> <td class="val">$<span py:replace="'%.2f' % product.price" /></td> </tr> </table> |
Şekil 3'te ürün görüntüleme sayfası gösterilir:
Şekil 3. Ürün görüntüleme sayfası
Denetleyici yöntemlerinin göz önünde bulundurmadığı nokta, SQLObject get
yöntemleri tarafından gönderilen SQLObjectNotFound
durumudur. Liste 16'da, bu olağandışı durumu yakalayan ve bunu bir NotFound
(Bulunamadı) biçimindeki temel HTTP 404 hatası olarak yeniden gönderen bir yeniden yazma işlemi (refactoring) gösterilmiştir:
Liste 16. Controller sınıfına hata işleme eklendi
from model import Category, Product from sqlobject import SQLObjectNotFound from cherrypy import NotFound from turbogears import controllers, expose, url class Root(controllers.Root): @expose("tgcommerce.templates.category") def category(self, categoryID): try: category = Category.get(categoryID) except SQLObjectNotFound: raise NotFound() return dict(category=category) @expose("tgcommerce.templates.product") def product(self, productID): try: product = Product.get(productID) except SQLObjectNotFound: raise NotFound() return dict(product=product) |
Eksik nesnelerin işlenmesi için bir 404 hatası göndermek yerine izlenen bir başka strateji de yeniden yönlendirmektir. Bu, turbogears.redirect(...)
yöntemi kullanılarak gerçekleştirilir:
Liste 17. Yeniden yönlendirme örneği
from turbogears import redirect try: object = ClassName.get(objectID) except SQLObjectNotFound: raise redirect("/path_to_redirect") |
Çalışan bir alışveriş sepetinizin olması için, istekler arasında durumu korumak üzere oturumlarınızın etkinleştirilmiş olması gerekir. Oturumlar, yapılandırma dosyasında session_filter.on
değerinin True
olarak ayarlanmasıyla etkinleştirilir.
Liste 18. Yapılandırma dosyasında (dev.cfg) etkinleştirilen oturumlar
session_filter.on = True sqlobject.dburi="notrans_sqlite:///path/to/devdir/TG-Commerce/tgcommerce.database" server.environment="development" autoreload.package="tgcommerce" |
Geçerli alışveriş sepetini her bir sayfada görüntülemek için, HTML'yi her bir sayfaya kopyalayıp yapıştırmak yerine ana şablon dosyasına yerleştirebilirsiniz:
Liste 19. Ana kid şablonunda (master.kid) içerilen alışveriş sepeti
<html> <body> ... <div id="shopping-cart"> Shopping Cart: <span id="cart-qty" py:content="cart.total_quantity" /> items ($<span id="cart-amt" py:content="'%.2f' % cart.total_price" />) </div> </body> </html> |
Yukarıdaki şablon değişikliği tek başına başarısız olacaktır, çünkü denetleyici yöntemlerinden gelen dönüş sözlüklerinde bir cart
değeri bulunmamaktadır.
Liste 20'de, oturumda saklanmakta olan sepeti içerecek
products
yönteminde yapılacak değişikliği gösterir.
Liste 20. Denetleyicilerden dönen alışveriş sepeti nesnesi
@expose("tgcommerce.templates.product") def product(self, productID): try: product = Product.get(productID) except SQLObjectNotFound: raise NotFound() return self.results(product=product) def results(self, cart=None, **kw): if not cart: cart = self.get_cart() kw['cart'] = cart return kw def get_cart(self): cartID = session.get("cartID", None) cart = None if cartID: try: cart = Order.get(cartID) except SQLObjectNotFound: pass if cart is None: cart = Order() session["cartID"] = cart.id return cart |
results
(sonuçlar) yöntemi, geçerli Order
(Sipariş) nesnesini alacak ya da böyle bir nesne yoksa ya da bulunamazsa yenisini yaratacak olan get_cart
'ı çağırır. Bu değişikliğin, index
ve category
yöntemlerinde de yer alması gerekir.
Bu alışveriş sepeti örneğini teknik terimlerle açıklamak gerekirse, ürünü sepete ekle işlevi, sayfayı yenilemeksizin bir Ajax çağrısı yoluyla gerçekleştirilir. Konuya aşina olmayanlar için açıklamak gerekirse, Ajax, Asynchronous JavaScript + XML sözcüklerinin kısaltması olan (Zamanuyumsuz JavaScript + XML) bir Web uygulaması kalıbıdır. Ajax terimini ilk kez tanımlayan makale, Kaynaklar bölümünde listelenmiştir.
Bu örnekte, taşıma biçimi olarak XML yerine JavaScript Object Notation (JSON) kullanılmaktadır. JSON çok daha basittir ve hem TurboGears, hem de MochiKit tarafından yerel olarak desteklenir. Her ne kadar zamanuyumsuz JavaScript'in JSON ile kullanılması giderek daha da yaygınlaşıyorsa da, Ajaj kısaltması aynı derecede akılda kalıcı olmadığı için, bunun adı Ajax olarak kalacaktır.
Aşağıda, belirtilen ürünü alıp bunu oturumda geçerli olan sepete ekleyen add_to_cart
(sepete ekle) denetleyici yöntemi gösterilmiştir. Yöntem, toplam fiyat ve sepetteki ürünlerin miktarıyla birlikte bu sepet nesnesini döndürür:
Liste 21. add_to_cart (sepete ekle) denetleyici yöntemi
@expose() def add_to_cart(self, productID): cart = self.get_cart() product = Product.get(productID) cart.add_product(product, 1) return self.results(cart=cart, price=cart.total_price, quantity=cart.total_quantity) |
expose
yönteminin bir şablon adıyla birlikte sağlanmamış olduğuna dikkat edin. Bunun nedeni, yöntemin doğrudan bir tarayıcıdan çağrılacak ve HTML'de oluşturulacak olmamasıdır. add_to_cart
sayfasını
(http://localhost:8080/add_to_cart/1) doğrudan bir tarayıcıdan ya da curl
gibi bir araç yoluyla görüntülerseniz, size işlenmemiş JSON verileri verilir: {"tg_flash":null, "price":24, "cart":{"id":24},
"quantity":1}
.
İstemciden (tarayıcıdan) sunucudaki add_to_cart
denetleyici yöntemine gelen JavaScript çağrısı çok basittir. MochiKit, bir URL'yi alıp deferred (ertelenmiş) olarak bilinen bir nesneyi döndüren ve loadJSONDoc
olarak adlandırılan bir işlev sağlar. Bu ertelenmiş nesneyi, zamanuyumsuz çağrı bir yanıt döndürdüğünde bir geri arama yöntemi tanımlamak için kullanabilirsiniz.
Liste 22. Alışveriş sepeti AJAX mantığı (cart.js)
function addToCart(productID) { var deferred = loadJSONDoc('/add_to_cart/' + productID); deferred.addCallback(updateCart); } function updateCart(results) { $("cart-amt").innerHTML = numberFormatter("#.00")(results["price"]); $("cart-qty").innerHTML = results["quantity"]; } |
Dönüşün ardından updateCart
işlevine başvurulur ve results
(sonuçlar) adı verilen çağrışımlı bir dizi değişkeniyle JSON değerleri sağlanır. İşlev tanıtıcıyı ve innerHTML
özniteliğini kullanarak sepetin tutarını ve miktarını günceller. Bunun üzerinde, fiyata ilişkin önemli basamakları belirtmek için MochiKit numberFormatter
işlevi kullanılır.
Bundan sonra en son adım, geçerli ürün tanıtıcısını geçirerek yukarıdaki addToCart
işlevini çağıran bir bağlantı eklemektir. Ayrıca, MochiKit.js ve cart.js dosyalarınızı komut dosyası etiketleri olarak şablonunuza eklemeniz gerekir:
Liste 23. Add to cart (Sepete ekle) JavaScript çağrısının ürün sayfasına (product.kid) eklenmesi
<head> ... <script src="/tg_js/MochiKit.js" type="text/javascript" /> <script src="/static/javascript/cart.js" type="text/javascript" /> </head> <body> ... <table> ... <tr> <td colspan="2" align="right"> <a href="#" onclick="addToCart(${product.id})">Add To Cart</a> </td> </tr> </table> </body> |
Sonuç: TurboGears ile Django'nun Karşılaştırılması
Hem Django, hem de TurboGears, Python dilini kullanarak Web sitelerinin esnek ve hızlı bir biçimde geliştirilmesini sağlayan MVC biçimindeki çerçevelerdir. Gereksinimleriniz için en uygun olanı seçerken aşağıdaki farkları göz önünde bulundurun:
-
Geçmişe ilişkin bilgi:
Her iki proje de, Ruby on Rails gibi, var olan uygulamalardan alındı ve açık kaynak topluluğuna yayınlandı. Django daha uzun zamandır piyasada ve ilk olarak günde milyonlarca sayfa görünümü sunan bir çevrimiçi gazeteden doğdu. TurboGears ise, hala geliştirilmeye devam eden zengin istemci RSS News Reader (Haber Okuyucu) uygulamasından doğdu. TurboGears, Django'ya göre topluluk tarafından daha fazla yönlendirilen bir çerçevedir, çünkü TurboGears var olan açık kaynak bileşenleri kullanılarak oluşturulmuştur.
Her bir projenin farklı geçmişleri, bunların farklı proje önceliklerine sahip olmasına neden olmuştur. Yüksek talepli ve hızlı çevrimiçi gazetecilik dünyasından gelen Django ekibi, içeriğe dayalı uygulamaların hızlı bir biçimde oluşturulmasını ve kolayca değiştirilmesini sağlayan bir çerçeve üzerinde odaklandı. Tüketim malları temeline sahip TurboGears ekibiyse, zengin istemci uygulamalarına ve takılıp çıkarılabilen mimariye yöneldi.
-
URL'ler:
TurboGears'ın istek dağıtma mekanizması, denetleyici sınıfı ve yöntem adları yoluyla yönlendirilir. Yeni bir denetleyici sınıfı ya da yöntemi eklediğinizde, eklenenler otomatik olarak kullanılabilir hale gelir. Belirli bir denetleyiciyi yürüten yolu değiştirmeniz gerekirse, kodunuzu yeniden yapılandırmanız gerekir. Bunun tersine Django, URL yolu yapısını gerçek kuruluştan ayırarak URL'leri temel kodla eşlemek için ayrı bir normal anlatıma dayalı yapılandırma dosyası kullanır.
TurboGears sistemi, yeni sayfaların kullanılabilmesini sağlamak için yalnızca bir
expose
dekoratörünün varlığını gerektirdiğinden, Django'dan daha hızlı kurulur. Öte yandan, Django yapılandırma sistemi en üst düzeyde denetim ve esneklik sağlar. Django URL'leri, başlıca bir yeniden yazma işlemi (refactoring) sonrasında bir uygulamaya kolayca eklenebilir. Bu özellik, eski yer işaretleri ya da önbelleğe alınmış arama motoru sonuçlarının yol açtığı bağlantının bozulmasının (link rot) önlenmesine yardımcı olur. Bağlantı bozukluğu, Django'nun yaratması için tasarlanan içeriğe dayalı Web sitelerinin trafik düzeylerine ve kullanılabilirliğine ciddi zararlar verir. - Kodun yeniden kullanılması:
TurboGears ekibi, TG'nin var olan bileşenlerden oluşturulan bir proje olduğunu açık bir biçimde belirtmek için projelerini megaframework (mega çerçeve) olarak adlandırır. TurboGears ekibi en baştan yazmak yerine kullanılabilir olan en iyi açık kodu seçer ve bütünleştirir. TurboGears çerçevesinin sağladığı bir yan avantaj da, mega topluluklu bir mega proje olmasıdır. TG, TurboGears'ı oluşturan çekirdek bileşenlere ilgi ve katılım isteği duyulmasını sağlayan güçlü, merkezi bir güç haline gelmiştir. O, bütün gemileri yükselten gelgittir.
Diğer yandan Django, var olan Python bileşenlerinin henüz bugünkü kadar güçlü olmadığı 2003 yılında yaratılmıştı. Django Web yığını sıfırdan yaratıldı ve sonuç olarak günde milyonlarca ziyaretçi alan çeşitli Web sitelerini yaratmak için kullanılan sağlam bir çerçeve halini aldı. Ancak bazı kişiler, Django projesinin kodları yeniden kullanma özelliği olmadığı için NIH (Not Invented Here; Burada Keşfedilmedi) Sendromuyla karşılaşacağını ileri sürüyor. Django ekibinin konumunda, Python'da sıfırdan bir çerçeve yaratmak için yapılması gereken, var olan bileşenleri birbirine tutturmaktan daha zor değildir ve sonuçta daha bütün ve birörnek bir çerçeve yaratılır.
- JavaScript:
TurboGears, bir JavaScript kitaplığı olan MochiKit'e, çerçevesi bünyesinde birinci sınıf bir konum vermiştir. Ekip ayrıca "zengin" biçim öğeleri yaratmak amacıyla JavaScript'ten geniş biçimde yararlanan bir pencere bileşeni kitaplığı da yaratmıştır. Bu, TurboGears dünyasında bir zengin istemci (Ajax) geliştirmesinin ne kadar önemli olduğunu gösterir. Django ekibi, çerçevelerinde varsayılan değer olarak bir JavaScript kitaplığını içermeyi seçmemiş, ancak bu olasılığı tartışmıştır. Her iki proje de sizin JavaScript kitaplıklarını kullanmanızı hiçbir biçimde kısıtlamaz.
- Yönetim araçları:
Her iki projede de yönetim arabirimleri vardır. Django yönetim aracının hedef izleyicisi, bir uygulamaya her yeni işlev eklenmesinde özel araçların varlığını gerektirmeyecek, güzel görünümlü bir veri girişi aracına gereksinim duyan son kullanıcılardır. Diğer taraftan TurboGears yönetim aracı, temel bir veritabanı görüntüleyicisi ve düzenleyicisiyle birlikte bir tasarım araçları takımı sağladığı geliştiriciler üzerinde odaklanır.
- Lisans:
Django sıfırdan yaratıldığı için, projenin tamamı tek bir açık kaynak lisansı (BSD lisansı) kapsamındadır. Birden çok projeden oluşan TurboGears çerçevesinin çeşitli lisansları vardır. SQLObject, ORM aracı, LGPL'nin (Lesser General Public License) koruması altındadır ve buna göre, SQLObject kitaplığının kendi kaynak kodu değiştirilir ve dağıtılırsa, bu değişikliklerin herkes için sağlanması gerekir. Lisans, bunu kullanan uygulamaların açık kaynaklı olmasını gerektirmez. Yine de bazı firmalar, LGPL altında lisanslı bulunan yazılımın kullanılmasını engeller. Bu durumlarda, TG topluluğunda güçlü bir biçimde desteklenen bir başka ORM aracı olan SQLAlchemy aracını kullanmayı düşünebilirsiniz.
- Gerçek dünyadan örnekler:
Django ve TurboGears çerçeveleri tarafından desteklendiği bilinen siteleri listeleyen sayfalara ilişkin bağlantıları görmek için, Kaynaklar bölümüne bakın. Bu canlı uygulamalar, her bir araç ile neler yapılabileceğini gösterir.
Bilgi Edinme
- "Django ve Python ile Web için Geliştirme Yapın" (developerWorks, Haziran 2006), Ian'ın iki bölümlük dizisinin 1. Bölümü, Django'yu tanıtır.
- Python
öğreticisi , Python ile çalışmaya başlamanızı sağlar.
- SQLObject ana sayfası, varsayılan TurboGears nesne ile ilişkili eşleme (ORM) aracı hakkında daha fazla bilgi sağlar.
- Ajax çılgınlığını başlatan Ajax:
A New Approach to Web Applications (Ajax: Web Uygulamaları İçin Yeni Bir Yaklaşım) adlı makaleyi okuyun.
- developerWorks üzerinde Ajax ile ilgili daha fazla bilgi okuyabilirsiniz.
- Python Eggs paketinin bir parçası olan
easy_install
(kolay kuruluş) ile birlikte kurma araçlarının nasıl kurulacağını gösteren Building and Distributing Packages with setuptools (Kuruluş araçlarıyla Paketlerin Kurulması ve Dağıtılması).
- Trac, TurboGears kullanan Web sitelerini listeler.
- Django projesi, Django kullanan Web sitelerini listeler.
- developerWorks Linux alanında, Linux geliştiricileri için daha fazla kaynak bulabilirsiniz.
- developerWorks teknik etkinlikler ve Web yayınları sayesinde güncel bilgiler edinebilirsiniz.
Ürün ve teknoloji edinme
- Python.org, Python yorumlayıcıyı ve standart kitaplıkları yüklemek için kullanılacak bağlantılara erişebileceğiniz Python programlama dili ana sayfasıdır.
- TurboGears.com, TurboGears çerçevesinin ana sayfasıdır.
- TurboGears önizleme sitesi, 0.9 alfa sürümünün geçerli ana sayfasıdır.
- Kid, TurboGears için XML tabanlı bir şablon dilidir.
- CherryPy, TurboGears çerçevesinin temelini sağlayan, Python ile uyumlu, nesne yönelimli bir Web çerçevesidir.
- MochiKit, DOM ve Ajax desteği sağlayan, çok iyi sınanmış bir JavaScript kitaplığıdır.
- JSON
(JavaScript Object Notation), MochiKit ve TurboGears tarafından zamanuyumsuz ileti alışverişinde kullanılan basit bir veri değiş tokuşu biçimidir.
- SEK for Linux ürününü sipariş edin. Bu ürün, DB2®, Lotus®,
Rational®, Tivoli® ve WebSphere® üzerinde Linux için en güncel IBM deneme yazılımlarını içeren ikili DVD setidir.
- Doğrudan developerWorks sitesinden yükleyebileceğiniz IBM deneme yazılımını kullanarak bir sonraki geliştirme projenizi Linux üzerinde oluşturabilirsiniz.
Tartışma
- developerWorks Web günlüklerine bakın ve developerWorks topluluğuna katılın.
Brulant, Inc. şirketinde danışman müdür olarak çalışan Ian Maurer, tüketim malları ve perakende de dahil olmak üzere çeşitli sektörler için açık kaynak ve IBM WebSphere teknolojilerini kullanarak bütünleştirilmiş e-ticaret çözümleri geliştirme konusunda uzmanlaşmıştır. Ohio'nun kuzeydoğusunda yaşayan Ian, Cleveland Area Python Interest Group'un bir üyesidir. |