Turbogears - Hızlı Kılavuz

Web Çerçevesi nedir?

Web Uygulama Çerçevesi veya basitçe Web Çerçevesi, bir web uygulaması geliştiricisinin protokoller, iş parçacığı yönetimi vb. Gibi düşük seviyeli ayrıntılar hakkında endişelenmek zorunda kalmadan uygulamaları yazmasını sağlayan bir kitaplık ve modül koleksiyonunu temsil eder.

TurboGears nedir?

TurboGears, Python ile yazılmış bir web uygulaması çerçevesidir. İlk olarak 2005 yılında Kevin Dangoor tarafından oluşturulan TurboGears'ın (sürüm 2.3.7) en son sürümü, Mark Ramm ve Florent Aide liderliğindeki bir grup geliştirici tarafından yönetilmektedir.

TurboGears, Rails, Django, Struts, vb. Gibi çoğu modern web çerçevesinin yaptığı gibi Model-Görünüm-Denetleyici paradigmasını takip eder.

Model Görünümü Denetleyicisi

MVC, web uygulamaları geliştirmek için bir yazılım tasarım modelidir. Model Görünüm Denetleyici kalıbı üç bölümden oluşur -

  • Model - Modelin en düşük seviyesi, verilerin korunmasından sorumludur.

  • View - Bu, verilerin tamamının veya bir kısmının kullanıcıya gösterilmesinden sorumludur.

  • Controller - Model ve Görünüm arasındaki etkileşimleri kontrol eden Yazılım Kodu.

MVC, uygulama mantığını kullanıcı arabirimi katmanından ayırdığı ve endişelerin ayrılmasını desteklediği için popülerdir. Burada, Kontrolör uygulamaya yönelik tüm talepleri alır ve ardından Model ile birlikte çalışarak Görünüm tarafından ihtiyaç duyulan verileri hazırlar. Görünüm daha sonra Kontrolör tarafından hazırlanan verileri kullanarak nihai bir sunulabilir yanıt oluşturur. MVC soyutlaması aşağıdaki gibi grafiksel olarak gösterilebilir -

Model

Model, uygulamanın verilerini yönetmekten sorumludur. Görünümden gelen talebe yanıt verir ve ayrıca kontrolörün kendisini güncellemesi için gelen talimatlara yanıt verir.

Görünüm

Bir kontrolörün verileri sunma kararıyla tetiklenen, belirli bir formatta verilerin sunumu. AJAX teknolojisi ile entegre edilmesi çok kolay komut tabanlı şablonlama sistemleridir.

Kontrol eden, denetleyici

Denetleyici, kullanıcı girdisine yanıt vermekten ve veri modeli nesneleri üzerinde etkileşimler gerçekleştirmekten sorumludur. Kontrolör girişi alır, girişi doğrular ve ardından veri modelinin durumunu değiştiren iş operasyonunu gerçekleştirir.

TurboGears, bir dizi kitaplık ve araç üzerine inşa edilmiştir. Bu araçlar, TurboGears’ın farklı sürümleri arasında değişmiştir. Mevcut sürümün (ver 2.3.7) bileşenleri aşağıda listelenmiştir.

SQLAlchemy

Python kodu için Nesne ilişki eşlemesi (ORM) sağlayan açık kaynaklı bir SQL kitidir.

Genshi

Bu şablonlama motoru, TG uygulamalarının ön ucunu oluşturmak için kullanılır. Bir web şablonlama sistemi, dinamik web sayfalarını oluşturmak için bir şablonu belirli bir veri kaynağıyla birleştirir.

ToscaWidgets

Sunucu tarafı kontrolleri ile HTML formları oluşturmak için bir widget kitaplığıdır. Tosca, JavaScript widget'ları ve araç takımlarıyla bağlantı kurmak için bir ara yazılım görevi de görür.

Vites kutusu

Projeleri ve sunucu TurboGears uygulamalarını yönetmek için bir dizi komut sağlar. TurboGears uygulamaları, herhangi bir WSGI uyumlu web sunucusuna yerleştirilebilir.

Web Sunucusu Ağ Geçidi Arayüzü (WSGI), Python web uygulaması geliştirme için bir standart olarak benimsenmiştir. WSGI, web sunucusu ve web uygulamaları arasındaki evrensel arabirim için bir belirtimdir. Wsgiref paketi, WSGI'nin bir referans uygulamasıdır. Web TurboGears web çerçevesine WSGI desteği eklemek için kullanılır. Bu paketteki simple_server modülü, WSGI uygulamalarına hizmet veren basit bir HTTP sunucusu uygular. Bu eğitim sırasında geliştirilen uygulamaları test etmek için kullanacağız.

Önkoşul

Python 2.6 veya üstü. TurboGears’ın önceki sürümleri Python 3.X ile uyumlu değildi. Son sürüm Python 3.X'te iyi çalıştığını iddia ediyor. Ancak, TurboGears'ın resmi belgeleri hala Python 2.7 ortamına dayanmaktadır.

Aşağıdaki komut installs virtualenv -

pip install virtualenv

Bu komutun ihtiyacı administratorayrıcalıklar. Eklesudo before pipLinux / Mac OS'de. Windows kullanıyorsanız, Yönetici olarak oturum açın. Ubuntu'da virtualenv, paket yöneticisi kullanılarak kurulabilir.

Sudo apt-get install virtualenv

Yeni sanal ortam kurulduktan sonra bir klasörde oluşturulur.

mkdir newproj
cd newproj
virtualenv venv

İlgili ortamı etkinleştirmek için Linux/OS X

venv/bin/activate

açık Windows

venv\scripts\activate

Artık hazırız install TurboGearsbu ortamda. TurboGears'ın minimum kurulumu aşağıdaki komutla yapılır -

pip install TurboGears2

Yukarıdaki komut, sistem çapında kurulum için sanal ortam olmadan doğrudan çalıştırılabilir.

TurboGears'ı geliştirme araçlarıyla birlikte kurmak için aşağıdaki komutu kullanın -

pip install tg.devtools

TurboGears, hızlı bir şekilde tek dosya uygulamaları oluşturmayı mümkün kılan minimal bir moda sahiptir. Basit örnekler ve hizmetler, minimum bağımlılık kümesiyle hızlı bir şekilde oluşturulabilir.

Bir TG uygulamasındaki uygulama sınıfı, TGControllersınıf. Bu sınıftaki yöntemlere erişim için@expose dekoratör tgmodül. İlk uygulamamızda,index()yöntem uygulamamızın kökü olarak eşlenir. TGController sınıfının da şuradan içe aktarılması gerekir:tg modül.

from tg import expose, TGController
class MyController(TGController):
   @expose()
   def index(self):
      return 'Hello World turbogears'

Ardından, uygulamanın yapılandırmasını ayarlayın ve uygulama nesnesini bildirin. AppConfig sınıf yapıcısı burada iki parametre alır - minimum öznitelik true olarak ayarlanmış ve denetleyici sınıfı.

config = AppConfig(minimal = True, root_controller = RootController())
application = config.make_wsgi_app()

make_wsgi_app() function burada uygulama nesnesi oluşturur.

Bu uygulamaya hizmet verebilmek için artık HTTP sunucusunu başlatmamız gerekiyor. Daha önce de belirtildiği gibi kullanacağızsimple_server modül içinde wsgirefpaketi kurmak ve başlatmak için. Bu modüldemake_server() bağımsız değişken olarak bağlantı noktası numarası ve uygulama nesnesi gerektiren yöntem.

from wsgiref.simple_server import make_server
server = make_server('', 8080, application)
server.serve_forever()

Bu, uygulamamızın localhost'un 8080 numaralı bağlantı noktasında hizmet vereceği anlamına gelir.

Aşağıdaki, ilk TurboGears uygulamamızın tam kodudur -

app.py

from wsgiref.simple_server import make_server
from tg import expose, TGController, AppConfig

class MyController(TGController):

   @expose()
   def index(self):
      return 'Hello World TurboGears'
		 
config = AppConfig(minimal = True, root_controller = MyController())
application = config.make_wsgi_app()

print "Serving on port 8080..."
server = make_server('', 8080, application)
server.serve_forever()

Yukarıdaki betiği Python kabuğundan çalıştırın.

Python app.py

Giriş http://localhost:8080 'Hello World TurboGears' mesajını görüntülemek için tarayıcının adres çubuğuna.

tg.devtoolsTurboGears, Gearbox içerir. Daha karmaşık TG projelerinin yönetimi için yararlı olan bir dizi komuttur. Tam yığın projeleri aşağıdaki Gearbox komutuyla hızlı bir şekilde oluşturulabilir -

gearbox quickstart HelloWorld

Bu adında bir proje yaratacak HelloWorld.

Bir TurboGears projesi aşağıdaki dizinleri içerir -

  • Config - Proje kurulumu ve yapılandırmasının dayandığı yer

  • Controllers - Tüm proje denetleyicileri, web uygulamasının mantığı

  • i018n - Desteklenen diller için çeviri dosyaları

  • Lib - Python işlevleri ve sınıfları yardımcı olur

  • Model - Veritabanı modelleri

  • Public Static Files - CSS, JavaScript ve resimler

  • Templates - Denetleyicilerimiz tarafından gösterilen şablonlar.

  • Tests - Yapılan Testler dizisi.

  • Websetup - Uygulama kurulumunda yürütülecek işlevler.

Proje nasıl kurulur

Bu projenin şimdi yüklenmesi gerekiyor. Birsetup.pyzaten projenin temel dizininde sağlanmıştır. Bu komut dosyası yürütüldüğünde proje bağımlılıkları yüklenir.

Python setup.py develop

Varsayılan olarak, proje kurulumu sırasında aşağıdaki bağımlılıklar yüklenir -

  • Beaker
  • Genshi
  • zope.sqlalchemy
  • sqlalchemy
  • alembic
  • repoze.who
  • tw2.forms
  • tgext.admin ≥ 0.6.1
  • WebHelpers2
  • babel

Kurulumdan sonra, kabukta aşağıdaki komutu vererek projeyi geliştirme sunucusunda sunmaya başlayın -

Gearbox serve –reload –debug

Önceden oluşturulmuş bir örnek projeye hizmet etmek için yukarıda belirtilen komutu izleyin. Açıkhttp://localhost:8080tarayıcıda. Bu hazır örnek uygulama, TurboGears çerçevesinin kendisi hakkında kısa bir giriş sağlar.

Bu Hello projesinde, varsayılan denetleyici denetleyiciler dizininde şu şekilde oluşturulur: Hello/hello/controllers.root.py. Hadimodify root.py aşağıdaki kodla -

from hello.lib.base import BaseController
from tg import expose, flash

class RootController(BaseController):
   movie = MovieController()
   @expose()
   def index(self):
      return "<h1>Hello World</h1>"
		
   @expose()
   def _default(self, *args, **kw):
      return "This page is not ready"

Temel çalışan bir uygulama hazır olduğunda, denetleyici sınıfına daha fazla görünüm eklenebilir. İçindeMycontroller yukarıdaki sınıf, yeni bir yöntem sayHello()eklendi. @expose() dekoratör ekler /sayHelloURL'si. Bu işlev, URL'den parametre olarak bir adı kabul etmek için tasarlanmıştır.

'Gearbox service' komutuyla sunucuyu başlattıktan sonra, http://localhost:8080. Aşağıdaki URL'ler girilse bile tarayıcıda Merhaba Dünya mesajı görüntülenecektir -

http://localhost:8080/

http://localhost:8080/index

Tüm bu URL'ler, RootController.index()yöntem. Bu sınıfta ayrıca_default()Bir URL herhangi bir belirli işlevle eşlenmediğinde çağrılacak yöntem. URL'ye yanıt, @expose () dekoratörü tarafından bir işleve eşlenir.

URL'den açık bir işleve bir parametre göndermek mümkündür. Aşağıdaki işlev, ad parametresini URL'den okur.

@expose()
def sayHello(self, name):
   return '<h3>Hello %s</h3>' %name

Aşağıdaki çıktı, tarayıcıda URL'ye yanıt olarak görülecektir - http://localhost:8080/?name=MVL

Hello MVL

TurboGears, URL parametrelerini otomatik olarak işlev bağımsız değişkenleriyle eşler. RootController sınıfımız BaseController'dan miras alınır. Bu şu şekilde tanımlanır:base.py içinde lib folder uygulama.

Kodu aşağıdaki gibidir -

from tg import TGController, tmpl_context
from tg import request

__all__ = ['BaseController']

def __call__(self, environ, context):
   tmpl_context.identity = request.identity
   return TGController.__call__(self, environ, context)

TGController.__call__ isteğin yönlendirildiği Controller yöntemine gönderir.

HTML içeriği tarayıcıya döndürülebilmesine rağmen, daha gelişmiş çıktı için şablon motorunun kullanılması her zaman tercih edilir. Gearbox tarafından 'hızlı başlatılan' bir tam yığın projesinde, Genshi varsayılan şablon oluşturucu olarak etkinleştirilir. Ancak minimal bir uygulamada, Genshi'nin (veya jinja gibi başka herhangi bir şablon motorunun) yüklenmesi ve etkinleştirilmesi gerekir. Genshi şablon motoru, saf xhtml'de şablonlar yazmaya izin verir ve bunları derleme sırasında sorunları tespit etmek ve bozuk sayfaların sunulmasını önlemek için doğrular.

Şablonlar, noktalı gösterim kullanılarak belirtilir. Merhaba projemizde şablon web sayfalarını saklamak için bir şablon dizini sağlanmıştır. Bu nedenlesample.html olarak anılacaktır hello.templates.sample(uzantı belirtilmedi). TurboGears, bu şablonu, açık bir dekoratör aracılığıyla, denetleyici yöntemini ona bağlamak içintg.render_template() işlevi.

Açığa çıkan denetleyici işlevi bir Python sözlük nesnesi döndürür. Bu sözlük nesnesi de bağlantılı şablona aktarılır. Şablondaki yer tutucular sözlük değerleriyle doldurulur.

Başlangıç ​​olarak, düz html komut dosyası içeren bir web sayfası görüntüleyelim. Açığa çıkan kontrolör birnull dictionary object HTML komut dosyası içinde ayrıştırılacak herhangi bir veri göndermek niyetinde değiliz.

Örnek HTML Nasıl Oluşturulur

bizim sample.htmlaşağıda verilmiştir. Projenin şablonlar dizininde saklandığından emin olun.

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
   </body>
</html>

Ekle sample() işlev root.py ve sample.html'yi bunun üzerinden gösterin.

@expose("hello.templates.sample")
   def sample(self):
      return {}

Aşağıdaki sonuç, bir URL olduğunda tarayıcıda görüntülenecektir. http://localhost:8080/sample web sunucusu başlatıldıktan sonra girilir.

Yukarıda bahsedildiği gibi, bir sözlük nesnesi bir Genshi şablonuna parametreler koleksiyonu olarak gönderilir. Bu şablon, kontrolörden alınan parametrelerle dinamik olarak doldurulan 'yer tutucuları' içerir.

Değiştirelim sample() örnek şablona bir sözlük nesnesi göndermek için işlev.

@expose("hello.templates.sample")
   def sample(self,name):
      mydata = {'person':name}
      return mydata

Oluşturmak sample.html şablonlar klasöründe (templates\sample.html)

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, my name is ${person}!.</h2>
   </body>
</html>

Yukarıdaki HTML kodunda, ${person}yer tutucudur. Girişhttp://localhost:8080/sample?name=MVLtarayıcıda URL olarak. Bu URL ile eşleştirildisample()Kök denetleyicimizde yöntem. Bir sözlük nesnesi döndürür. Bu, şablonlar dizinindeki bağlantılı şablon sayfası sample.html tarafından seçilir. $ {Person} daha sonra web sayfasında MVL ile değiştirilir.

HTML form verilerine bir denetleyici işlevinde erişmek de mümkündür. HTML formu, form verilerini göndermek için kullanır.

Http Protokolü, dünya çapında ağda veri iletişiminin temelidir. Bu protokolde belirtilen URL'den farklı veri alma yöntemleri tanımlanmıştır. Aşağıdaki tablo farklı http yöntemlerini özetlemektedir -

Sr.No. HTTP Yöntemleri ve Açıklaması
1

GET

Verileri şifrelenmemiş biçimde sunucuya gönderir. En yaygın yöntem.

2

HEAD

GET ile aynı, ancak yanıt gövdesi yok

3

POST

HTML form verilerini sunucuya göndermek için kullanılır. POST yöntemi ile alınan veriler sunucu tarafından önbelleğe alınmaz.

4

PUT

Hedef kaynağın tüm mevcut temsillerini yüklenen içerikle değiştirir.

5

DELETE

Bir URL tarafından verilen hedef kaynağın tüm mevcut temsillerini kaldırır

Bir HTML Formu Oluşturmak

Bir HTML Formu oluşturalım ve form verilerini bir URL'ye gönderelim. Aşağıdaki komut dosyasını login.html olarak kaydedin

<html>
   <body>
      <form action = "http://localhost:8080/login" method = "get">
         <p>Enter Name:</p>
         <p><input type = "text" name = "nm" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
   </body>
</html>

Bu forma girilen veriler şu adrese gönderilecektir: ‘/login’ URL. Şimdi bir kontrolör işlevi oluşturunloginpage() ve yukarıdaki html sayfasını ona gösterin.

@expose("hello.templates.login")
   def loginpage(self):
      return {}

Form verilerini almak için bir login()parametreleri olarak form özniteliklerine sahip denetleyici. Buraya‘nm’ giriş formundaki metin giriş alanının adıdır, aynı, login () fonksiyonunun bir parametresi olarak kullanılır.

@expose("hello.templates.sample")
   def login(self, nm):
      name = nm
      return {'person':name}

Görüldüğü üzere giriş formundan alınan veriler sample.html şablonuna (daha önce kullanılmış) gönderilmektedir. Tarafından ayrıştırılırGenshi template engine aşağıdaki çıktıyı oluşturmak için -

POST Yöntemi

HTML formu, verileri eylemdeki URL'ye göndermek için POST yöntemini kullandığında, form verileri URL'de gösterilmez. Kodlanmış veriler birdictdenetleyici işlevi tarafından bağımsız değişken. **kw Aşağıdaki argüman, veri için tutan sözlük nesnesidir.

HTML formu iki giriş metin alanı içerir.

<html>
   <body>
	
      <form action = "http://localhost:8080/marks" method = "post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
		
   </body>	
</html>

marks() denetleyici, form verilerini alır ve gönderir sample.htmlşablonu. Kodroot.py aşağıdaki gibidir -

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
   def marksform(self):
      return {}
		
   @expose("hello.templates.sample")
   def marks(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      ttl = int(phy)+int(maths)
      mydata = {'phy':phy, 'maths':maths, 'total':ttl}
      return mydata

Son olarak, sample.html şablonu aşağıdaki gibidir -

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
      <h3>Marks in Physics: ${phy}.</h3>
      <h3>Marks in Maths: ${maths}.</h3> <h3>Total Marks: ${total}</h3>
   </body>
	
</html>

Sunucuyu başlatın (zaten çalışmıyorsa)

Gearbox server –reload –debug

Giriş http://localhost::8080/marksform tarayıcıda

sample.html aşağıdaki çıktıyı oluşturacak -

Genshi, XML tabanlı bir şablon dilidir. BenzerKid, daha önce TurboGears’ın önceki sürümleri için şablon motoruydu. Genshi ve Kid gibi diğer iyi bilinen şablon dillerinden esinlenmiştir.HSLT, TAL ve PHP.

Bir Genshi şablonu, işleme yönergelerinden oluşur. Bu Yönergeler, bir şablondaki öğeler ve özniteliklerdir. Genshi yönergeleri bir ad alanında tanımlanırhttp://genshi.edgewall.org/. Bu nedenle, bu ad alanının şablonun kök öğesinde bildirilmesi gerekir.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
...
</html>

Yukarıdaki beyan, varsayılan isim alanının XHTML olarak ayarlandığı ve Genshi direktiflerinde 'py' öneki olduğu anlamına gelir.

Genshi Direktifleri

Genshi'de bir dizi direktif tanımlanmıştır. Aşağıdaki liste Genshi direktiflerini sıralar -

  • py:if
  • py:choose
  • py:for
  • py:def
  • py:match
  • py:with
  • py:replace
  • py:content
  • py:attrs
  • py:strip

Koşullu Bölümler

Genshi içeriğin koşullu olarak oluşturulması için iki yönerge sağlar− py: if ve py: select.

py: if

Bu yönergenin öğesinin içeriği, yalnızca içindeki ifade if clausedoğru olarak değerlendirilir. Şablon bağlamındaki verilerin{‘foo’:True, ‘bar’:’Hello’}, aşağıdaki yönerge -

<div>
   <b py:if = "foo">${bar}</b>
</div>

sonuçlanacak

Hello

Ancak bu çıktı, eğer ‘foo’ is set to False.

Bu yönerge aynı zamanda öğe olarak da kullanılabilir. Bu durumda<py:if> karşılık gelen tarafından kapatılmalıdır </py:if>

<div>
   <py:if test = "foo">
      <b>${bar}</b>
   </py:if>
</div>

py: seçmek

Gelişmiş koşullu işlem, aşağıdakilerin kullanılmasıyla mümkündür: py:choose ile bütünlüğünde py:when ve py:otherwisedirektifler. Bu özellik benzerdirswitch – case inşa etmek C/C++.

İçinde ifade py:choose yönerge ile tanımlanan farklı değerlerle kontrol edilir py:whenalternatifler ve ilgili içerikler işlenecektir. Varsayılan bir alternatif şu şekilde sağlanabilir:py:otherwise direktif.

<div py:choose = "foo”>
   <span py:when = "0">0</span>
   <span py:when = "1">1</span>
   <span py:otherwise = "">2</span>
</div>

Aşağıdaki örnek, py:choose ve py:whendirektifler. HTML formu, verileri URL'ye gönderir / işaretler. marks() işlev, işaretleri ve sonuçları bir sözlük nesnesi biçiminde yeniden total.htmlşablonu. Koşullu gösterimiresult Pass/Fail kullanılarak elde edilir py:choose ve py:when direktifler.

İşaret girmenin HTML betiği (marks.html) aşağıdaki gibidir -

<html>
   <body>
      <form action = "http://localhost:8080/marks" method = "post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
   </body>
</html>

Tam kodu root.pyŞöyleki. marks() kontrolör işaretler ve sonuç gönderiyor total.html şablon -

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
      def marksform(self):
      return {}
		
   @expose("hello.templates.total")
      def marks(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      ttl = int(phy)+int(maths)
      avg = ttl/2
		
      if avg ≥ 50:
         mydata = {'phy':phy, 'maths':maths, 'total':ttl, 'result':2}
      else:
         mydata = {'phy':phy, 'maths':maths, 'total':ttl,'result':1}
	
      return mydata

total.html şablonlar klasöründe sözlük verilerini alır ve aşağıdaki gibi koşullu olarak html çıktısında ayrıştırır -

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
      <h3>Marks in Physics: ${phy}.</h3> <h3>Marks in Maths: ${maths}.</h3>
      <h3>Total Marks: ${total}</h3>
		
      <div py:choose = "result">
         <span py:when = "1"><h2>Result: Fail</h2></span>
         <span py:when = "2"><h2>Result: Pass</h2></span>
      </div>
		
   </body>
</html>

Sunucuyu başlatın (zaten çalışmıyorsa)

Gearbox server –reload –debug

Giriş http://localhost::8080/marksform tarayıcıda -

total.html aşağıdaki çıktıyı oluşturacak -

py: için

Element in py: for yönergesi yinelenebilir bir Python List nesnesindeki her öğe için tekrarlanır. Eğeritems = [1,2,3] bir şablon bağlamında mevcutsa, py: yönergesi için - izlenerek yinelenebilir

<ul>
   <li py:for = "item in items">${item}</li>
</ul>

Aşağıdaki çıktı işlenecek -

1
2
3

Aşağıdaki örnek, py kullanılarak total.html şablonunda oluşturulan HTML form verilerini gösterir: for yönergesi aşağıdaki gibi de kullanılabilir -

<py:for each = "item in items">
   <li>${item}</li>
</py:for>

HTML Form Komut Dosyası

<html>
   <body>
	
      <form action = "http://localhost:8080/loop" method="post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Chemistry:</p>
         <p><input type = "text" name = "che" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
		
   </body>
</html>

loop() denetleyici form verilerini okur ve bir liste nesnesi biçiminde total.template'e gönderir.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
   def marksform(self):
   return {}
	
   @expose("hello.templates.temp")
   def loop(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      che = kw['che']
      l1 = []
      l1.append(phy)
      l1.append(che)
      l1.append(maths)
		
   return ({'subjects':['physics', 'Chemistry', 'Mathematics'], 'marks':l1})

Temp.html şablonu, dict nesnesinin içeriğini bir tablo biçiminde işlemek için py: for döngüsünü kullanır.

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/" lang = "en">
	
   <body>
      <b>Marks Statement</b>
      <table border = '1'>
         <thead>
            <py:for each = "key in subjects"><th>${key}</th></py:for>
         </thead>
         <tr>
            <py:for each = "key in marks"><td>${key}</td></py:for>
         </tr>
      </table>
   </body>
</html>

Sunucuyu başlatın (zaten çalışmıyorsa)

gearbox server –reload –debug

Giriş http://localhost::8080/marksform tarayıcıda.

Yukarıdaki form gönderildiğinde aşağıdaki çıktı tarayıcıda görüntülenecektir.

py: def

Bu yönerge, bir makro oluşturmak için kullanılır. Makro, yeniden kullanılabilir bir şablon kod pasajıdır. Bir Python işlevi gibi, bir adı vardır ve isteğe bağlı olarak parametrelere sahip olabilir. Bu makronun çıktısı şablonun herhangi bir yerine eklenebilir.

Py: def yönergesi aşağıdaki sözdizimini izler -

<p py:def = "greeting(name)">
   Hello, ${name}!
</p>

Bu makro bir değişken değeri ile 'isim' parametresine dönüştürülebilir.

${greeting('world')} ${greeting('everybody)}

Bu yönerge, aşağıdaki gibi başka bir sözdizimi sürümüyle de kullanılabilir -

<py:def function = "greeting(name)">
   <p>Hello, ${name}! </p>
</py:def>

Aşağıdaki örnekte, macro() denetleyici root.py gönderir dict makro.html şablonuna name1 ve name2 iki anahtarlı nesne.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.macro')
   def macro(self):
      return {'name1':'TutorialPoint', 'name2':'TurboGears'}

Bu macro.html şablonu selamlama adı verilen bir makronun tanımını içerir. Kontrolörden alınan veriler için karşılama mesajı oluşturmak için kullanılır.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <body>
      <h2>py:def example</h2>
		
      <div>
         <div py:def = "greeting(name)">
            Hello, Welcome to ${name}!
         </div>
				
         <b>
            ${greeting(name1)} ${greeting(name2)}
         </b>
			
      </div>
   </body>
</html>

Sunucuyu dişli kutusunu kullanarak başlatın

gearbox serve –reload –debug

Tarayıcıya aşağıdaki URL'yi girerek makro () denetleyicisini çağırın -

http://localhost:8080/macro

Aşağıdaki çıktı tarayıcıda işlenecek -

py: ile

Bu yönerge, yerel değişkenlere ifade atamanıza izin verir. Bu yerel değişkenler, ifadeyi daha az ayrıntılı ve daha verimli hale getirir.

X = 50'nin bir şablon için bağlam verisinde verildiğini varsayarsak, aşağıdaki py: with yönergesi olacaktır -

<div>
   <span py:with = "y = 50; z = x+y">$x $y $z</span>
</div>

Aşağıdaki çıktıyla sonuçlanacaktır -

50 50 100

Py: with directive için alternatif bir sürüm de mevcuttur -

<div>
   <py:with = "y = 50; z = x+y">$x $y $z</py:with>
</div>

Aşağıdaki örnekte, macro () controller name, phy ve maths anahtarlarıyla bir dict nesnesi döndürür.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.macro')
   def macro(self):
      return {'name':'XYZ', 'phy':60, 'maths':70}

Macro.html şablonu py: with yönergesini kullanarak phy ve maths anahtarlarının değerlerini ekler.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <body>
      <h2>py:with example</h2>
      <h3>Marks Statement for : ${name}!</h3> <b>Phy: $phy Maths: $maths <span py:with = "ttl = phy+maths">Total: $ttl</span>
      </b>
		
   </body>
	
</html>

Tarayıcı, URL'ye yanıt olarak aşağıdaki çıktıyı oluşturacaktır http://localhost:8080/macro

Yapı Manipülasyonu Direktifleri

py:attrs yönerge öğeye öznitelikler ekler, değiştirir veya öznitelikleri kaldırır.

<ul>
   <li py:attrs = "foo">Bar</li>
</ul>

Eğer foo = {‘class’:’collapse’} yukarıdaki kod parçacığının işleyeceği bir şablon bağlamında mevcuttur.

<ul>
   <li class = "collapse">Bar</li>
</ul>

py:content yönerge, ifadenin değerlendirilmesinin sonucuyla iç içe geçmiş içeriği değiştirir -

<ul>
   <li py:content = "bar">Hello</li>
</ul>

Bağlam verilerinde bar = 'Bye' verildiğinde, bu,

<ul>
   <li>Bye</li>
</ul>

py:replace yönerge, ifadenin değerlendirilmesinin sonucuyla öğenin kendisini değiştirir -

<div>
   <span py:replace = "bar">Hello</span>
</div>

Bağlam verilerinde bar = 'Bye' verildiğinde,

<div>
   Bye
</div>

Başka bir XML belgesinin içeriği (özellikle HTML belgesi), geçerli belgeye dahil etme etiketleri kullanılarak dahil edilebilir. Böyle bir eklemeyi etkinleştirmek için, XInclude ad alanı HTML belgesinin kök öğesinde bildirilmelidir.

<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:xi = "http://www.w3.org/2001/XInclude >

Yukarıdaki bildirim, içerme yönergesinin şunu içerdiğini belirtir: ‘xi’önek. Geçerli belgeye başka bir html sayfasının içeriğini eklemek için xi: include direktifini aşağıdaki gibi kullanın -

<xi:include href = "somepage.html" />

Aşağıdaki örnekte, root.py include.html'yi açığa çıkaran include () denetleyicisini içerir.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.include')
   def include(self):
      return {}

Başlık ve Altbilgi HTML

İnclude.html'de, include ad alanı bildirilir ve heading.html ve footer.html'nin içerikleri eklenir. İşte şablonların HTML komut dosyası \ include.html -

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:xi = "http://www.w3.org/2001/XInclude">
	
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <xi:include href = "heading.html" />
      <h2>main content </h2>
      <xi:include href = "footer.html" />
   </body>
	
</html>

İşte şablonlar \ heading.html kodu -

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h1>This is page Header</h1>
   </body>
</html>

Aşağıdaki şablonlar \ footer.html

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h3>This is page footer</h3>
   </body>
</html>

Geliştirmeyi bir dişli kutusu kullanarak başlatın ve girin http://localhost:8080/includetarayıcıda. Oluşturulan çıktı aşağıda gösterildiği gibi olacaktır -

Bu şekilde modüler görünüm yapısı elde edilebilir. Xi: include yönergesinde belirtilen kaynak kullanılamıyorsa, bir hata ortaya çıkar. Böyle bir durumda, xi: fallback kullanılarak alternatif bir kaynak yüklenebilir.

<xi:include href = “main.html”>
   <xi:fallback href = ”default.html”/>
</xi.include>

İfadeler içerebilen href özelliği olarak içeriğin dahil edilmesi dinamik hale getirilebilir.

Root.py içine aşağıdaki denetleyiciyi ekleyin.

@expose('hello.templates.ref-include')
   def refinclude(self):
      return {'pages':['heading','main','footer']}

Aşağıdaki kodu şablonlar klasörüne ref-include.html olarak kaydedin.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   xmlns:xi = "http://www.w3.org/2001/XInclude">
	
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <xi:include href = "${name}.html" py:for = "name in pages" />
   </body>
	
</html>

Sunucuyu başlatmadan önce, şablonlar klasörünün heading.html, main.html ve footer.html içerdiğinden emin olun. Girişhttp://localhost:8082/refinclude aşağıdaki çıktıyı almak için tarayıcıda

@expose()dekoratör varsayılan olarak html içeriğini oluşturur. Ancak bu, şu şekilde ayarlanabilir:json content type. TurboGears, json oluşturmayı desteklertg.jsonify.JSONEncoder (**kwargs)sınıf. Json verilerini işlemek için, dekoratörün ortaya çıkması için json'u içerik türü olarak iletin.

@expose('json')
def jsondata(self, **kwargs):
   return dict(hello = 'World')

Tarayıcıya '/ jsondata' URL'si girilirse, şunu göstererek yanıt verir -

{"hello": "World"}

jsonp Oluşturma

jsonp, json ile doldurma anlamına gelir. Denetleyici tarafından işlev bağımsız değişkenleri olarak döndürülen tüm değerleri sağlayan bir javascript işlevine çağrı ile bir uygulama / javascript yanıtı sağlaması dışında json çıktısına benzer şekilde çalışır.

Jsonp oluşturmayı etkinleştirmek için önce uygulamanızdaki gerekli motorlar listesine eklemelisiniz - config/app_cfg.py -

base_config.renderers.append('jsonp')

Teşhir dekoratörünüzü aşağıdaki gibi yazın -

@expose('json')
@expose('jsonp')
def jsonpdata (self, **kwargs): 
   return dict(hello = 'World')

/ Jsonpdata? Callback = callme'ye erişirken şunu görmelisiniz -

callme({"hello": "World"});

Bazen bir web uygulaması birden fazla seviyeye sahip bir URL yapısı gerektirebilir. TurboGears, isteğinizi yerine getirebilecek uygun yöntemi bulmak için nesne hiyerarşisinde gezinebilir.

Gearbox ile 'hızlı başlatılan' bir proje, projenin lib klasöründe BaseController sınıfına sahiptir. 'Merhaba / merhaba / lib / base.py' olarak mevcuttur. Tüm alt denetleyiciler için temel sınıf görevi görür. Uygulamaya bir URL alt düzeyi eklemek için, BaseController'dan türetilen BlogController adlı bir alt sınıf tasarlayın.

Bu BlogController iki denetleyici işlevine sahiptir: index () ve post (). Her ikisi de blog.html ve post.html olmak üzere birer şablon göstermek için tasarlanmıştır.

Note - Bu şablonlar bir alt klasöre yerleştirilir - şablonlar / blog

class BlogController(BaseController):

   @expose('hello.templates.blog.blog')
   def index(self):
      return {}
		
   @expose('hello.templates.blog.post')
   def post(self):
      from datetime import date
      now = date.today().strftime("%d-%m-%y")
      return {'date':now}

Şimdi RootController sınıfında (root.py'de) bu sınıfın bir nesnesini aşağıdaki gibi bildirin -

class RootController(BaseController):
   blog = BlogController()

Üst düzey URL'ler için diğer denetleyici işlevleri, daha önce olduğu gibi bu sınıfta olacaktır.

Bir URL http://localhost:8080/blog/girildiğinde, BlogController sınıfı içindeki index () kontrolör işlevine eşlenecektir. Benzer şekilde,http://localhost:8080/blog/post post () işlevini çağıracaktır.

Blog.html ve post.html için kod aşağıdaki gibidir -

Blog.html

<html>
   <body>
      <h2>My Blog</h2>
   </body>
</html>

post.html

<html>
   <body>
      <h2>My new post dated $date</h2>
   </body>
</html>

Bir URL http://localhost:8080/blog/ girildiğinde, aşağıdaki çıktıyı üretecektir -

Bir URL http://localhost:8080/blog/post girildiğinde, aşağıdaki çıktıyı üretecektir -

Herhangi bir web uygulamasının en önemli yönlerinden biri, bir kullanıcı için kullanıcı arayüzünü sunmaktır. HTML, bir arayüz tasarlamak için kullanılan bir <form> etiketi sağlar. Metin girişi, radyo, seçim vb. Gibi form öğeleri uygun şekilde kullanılabilir. Kullanıcı tarafından girilen veriler, Http istek mesajı şeklinde GET veya POST yöntemi ile sunucu tarafındaki komut dosyasına gönderilir.

Sunucu tarafı komut dosyası, form öğelerini http istek verilerinden yeniden oluşturmalıdır. Bu nedenle, bu etkide, form öğelerinin iki kez tanımlanması gerekir - biri HTML'de ve yine sunucu tarafı komut dosyasında.

HTML formu kullanmanın diğer bir dezavantajı, form öğelerini dinamik olarak oluşturmanın (imkansız değilse de) zor olmasıdır. HTML'nin kendisi, kullanıcının girişini doğrulamak için hiçbir yol sağlamaz.

ToscaWidgets2

TurboGears, esnek bir form oluşturma ve doğrulama kitaplığı olan ToscaWidgets2'ye dayanır. ToscaWidgets'ı kullanarak Python betiğimizdeki form alanlarını tanımlayabilir ve bir HTML şablonu kullanarak işleyebiliriz. Tw2 alanına doğrulama uygulamak da mümkündür.

ToscaWidgets kitaplığı, birçok modülün bir koleksiyonudur. Bazı önemli modüller aşağıda listelenmiştir -

  • tw2.core- Temel işlevsellik sağlar. Bu modüldeki pencere öğelerinin son kullanıcılar için mevcut olması amaçlanmamıştır.

  • tw2.forms- Bu temel bir form kitaplığıdır. Alanlar, alan kümeleri ve formlar için pencere öğeleri içerir.

  • tw2.dynforms - Bu, dinamik form işlevselliği içerir.

  • tw2.sqla - Bu, SQLAlchemy veritabanı için bir arayüzdür.

tw2.forms

Özel formlar için bir temel görevi gören bir Form sınıfı içerir. İki sütunlu bir tablodaki alanları işlemede yararlı olan bir TableForm sınıfı vardır. ListForm, alanlarını sırasız bir liste halinde sunar.

Sr.No. Alanlar ve Açıklama
1

TextField

Tek satırlı bir metin giriş alanı

2

TextArea

Çok satırlı metin giriş alanı

3

CheckBox

Etiketli, işaretlenebilir bir dikdörtgen kutu sunar

4

CheckBoxList

Çoklu seçilebilir grup pf onay kutuları

5

RadioButton

Seçmek / seçimi kaldırmak için bir geçiş düğmesi

6

RadioButtonList

Birbirini dışlayan Radyo düğmeleri grubu

7

PasswordField

Textfield ile benzerdir ancak giriş tuşları açığa çıkmaz

8

CalendarDatePicker

Kullanıcının bir tarih seçmesine izin verir

9

SubmitButton

Form gönderme düğmesi

10

ImageButton

Üstte bir resim bulunan tıklanabilir düğme

11

SingleSelectField

Bir listeden tek bir öğenin seçilmesini sağlar

12

MultipleSelectField

Listeden birden çok öğenin seçilmesini sağlar

13

FileField

Dosya yükleme alanı

14

EmailField

Bir e-posta giriş alanı

15

URLField

URL girmek için bir giriş alanı

16

NumberField

Bir sayı döndürme kutusu

17

RangeField

Bir sayı kaydırıcısı

Aşağıdaki örnekte, bu widget'lardan bazılarını kullanan bir form oluşturulmuştur. Bu widget'ların çoğu tw2.forms'ta tanımlanırken, CalendarDateField tw2.Dynforms modülünde tanımlanmıştır. Dolayısıyla tw2.core ile birlikte bu modüllerin ikisi de başlangıçta içe aktarılır -

import tw2.core as twc
import tw2.forms as twf
import tw2.dynforms as twd

ToscaWidgets formu, aşağıdakilerden türetilen bir sınıftır: tw2.forms.formtemel sınıf. Gerekli widget'lar bir Layout nesnesinin içine yerleştirilir. Bu örnekte,TableLayoutkullanıldı. Pencere Öğeleri iki sütunlu bir tabloda oluşturulur. İlk sütun başlığı ve ikinci sütun giriş veya seçim alanını gösterir.

Aşağıdaki yapıcı kullanılarak bir TextField nesnesi oluşturulur -

twf.TextField(size, value = None)

Belirtilmezse TextField nesnesi varsayılan bir boyut alır ve başlangıçta boştur. TextArea nesnesi bildirilirken satır ve sütun sayılarından bahsedilebilir.

twf.TextArea("",rows = 5, cols = 30)

NumberField nesnesi, yalnızca rakamları kabul edebilen bir TextField'dir. İçerideki sayıyı artırmak veya azaltmak için sağ sınırda yukarı ve aşağı oklar oluşturulur. Başlangıç ​​değeri, yapıcıda bir bağımsız değişken olarak da belirtilebilir.

twf.NumberField(value)

CalendarDatePicker kutusunun hemen sağında bir takvim düğmesi görüntülenir. Basıldığında bir tarih seçici açılır. Kullanıcı kutuya manuel olarak bir tarih yazabilir veya tarih seçiciden seçim yapabilir.

twd.CalendarDatePicker()

EmailField nesnesi bir TextField sunar, ancak içindeki metin e-posta biçiminde olmalıdır.

EmailID = twf.EmailField()

Aşağıdaki formda ayrıca bir RadioButtonList vardır. Bu sınıfın yapıcısı, options parametresinin bir değeri olarak bir List nesnesi içerir. Her seçenek için bir Radyo Düğmesi oluşturulacaktır. Varsayılan seçim, değer parametresi ile belirtilir.

twf.RadioButtonList(options = ["option1","option2"],value = option1)

CheckBoxList, listedeki her seçenek için onay kutuları oluşturur.

twf.CheckBoxList(options = [option1, option2, option3])

Açılır liste, bu ToscaWidgets kitaplığında SingleSelectfield olarak adlandırılır. Açılır listeden options parametresine karşılık gelen bir List nesnesindeki öğeler. Görünür başlık, istem_metni parametresinin bir değeri olarak ayarlanır.

twf.SingleSelectField(prompt_text = 'text', options=['item1', 'item2', 'item3'])

Varsayılan olarak, form, başlığında 'kaydet' yazan bir Gönder düğmesi görüntüler. Başka bir resim yazısı görüntülemek için, bir SubmitButton nesnesi oluşturun ve bunu değer parametresi olarak belirtin.

twf.SubmitButton(value = 'Submit')

Form, formun işlem parametresinin değeri olarak belirtilen bir URL'ye gönderilir. Varsayılan olarak, form verileri http POST yöntemiyle gönderilir.

action = 'URL'

Aşağıdaki kodda, AdmissionForm olarak adlandırılan bir form, yukarıda açıklanan widget'lar kullanılarak tasarlanmıştır. RootController sınıfından önce bu kodu root.py içine ekleyin.

class AdmissionForm(twf.Form):
   class child(twf.TableLayout):
      NameOfStudent = twf.TextField(size = 20)
      AddressForCorrespondance = twf.TextArea("", rows = 5, cols = 30)
      PINCODE = twf.NumberField(value = 431602)
      DateOfBirth = twd.CalendarDatePicker()
      EmailID = twf.EmailField()
      Gender = twf.RadioButtonList(options = ["Male","Female"],value = 'Male')
      Subjects = twf.CheckBoxList(options = ['TurboGears', 'Flask', 'Django', 'Pyramid'])

      MediumOfInstruction = twf.SingleSelectField(prompt_text = 'choose',
         options = ['English', 'Hindi', 'Marathi', 'Telugu'])
			
      action = '/save_form'
      submit = twf.SubmitButton(value ='Submit')

Şimdi bu kodu aşağıdaki şekilde kaydedin twform.html şablonlar dizininde -

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
   
   <head>
      <title>TurboGears Form Example</title>
   </head>
   
   <body>
      <div id = "tw form">
         ${form.display(value = dict(title = 'default title'))}
      </div>
   </body>
   
</html>

RootController sınıfında (root.py içinde), aşağıdaki denetleyici işlevini ekleyin -

@expose('hello.templates.twform')
def twform(self, *args, **kw):
   return dict(page = 'twform', form = MovieForm)

AdmissionForm sınıfında, stipulated/save_formeylem URL'si olarak. Dolayısıyla ekleyinsave_form() RootController'da işlev.

@expose()
def save_movie(self, **kw):
   return str(kw)

Sunucunun çalıştığından emin olun (dişli kutusu sunumunu kullanarak). Girişhttp://localhost:8080/twform tarayıcıda.

Gönder düğmesine basıldığında bu veriler şuraya gönderilecek: save_form() Form verilerini bir sözlük nesnesi biçiminde görüntüleyecek URL.

{
   'EmailID': u'[email protected]', 
   'NameOfStudent': u'Malhar Lathkar', 
   'Gender': u'Male', 
   'PINCODE': u'431602', 
   'DateOfBirth': u'2015-12-29', 
   'Subjects': [u'TurboGears', u'Flask', u'Django'], 
   'MediumOfInstruction': u'', 
   'AddressForCorrespondance': u'Shivaji Nagar\r\nNanded\r\nMaharashtra'
}

İyi bir Formlar pencere öğesi kitaplığı bir giriş doğrulama özelliğine sahip olmalıdır. Örneğin, kullanıcı, doğrulama için başka herhangi bir programa dayalı yönteme (JavaScript işlevi gibi) başvurmadan, zorunlu bir alana veri girmeye veya bir e-posta alanının geçerli bir e-posta içerip içermediğini doğrulamaya zorlanmalıdır.

ToscaWidgets Forms Library'nin eski sürümleri, doğrulama desteği için FormEncode modülüne güveniyordu. ToscaWidgets2 artık tw2.core modülünde yerleşik doğrulama desteğine sahiptir. Bununla birlikte, FormEncode doğrulama tekniklerini kullanmak yine de mümkündür.

ToscaWidgets formunu doğrulamaya tabi tutmak için @validate decorator kullanılır.

@validate(form, error_handler, validators)
  • ’form’ doğrulanacak ToscaWidgets form nesnesidir.

  • ‘error-handler’ form hatalarını işlemek için kullanılan denetleyici yöntemidir.

  • ‘validators’ FormEncode doğrulayıcıları içeren bir sözlük nesnesidir.

Doğrulayıcı Türleri

Tw2.core modülü, diğer doğrulayıcıların miras alındığı bir doğrulayıcı sınıfı içerir. Buna dayalı olarak özel bir doğrulayıcı tasarlamak da mümkündür. Önemli doğrulayıcılardan bazıları aşağıda açıklanmıştır -

LengthValidator- Bir değerin önceden belirlenmiş bir uzunluğa sahip olup olmadığını kontrol edin. Minimum ve maksimum limitler, minimum ve maksimum parametrelerle tanımlanır. Min ve maks altındaki ve üzerindeki uzunluklar için özel mesajlar, tooshort ve takım boyu parametresi olarak belirtilebilir.

tw2.core.LengthValidator(min = minval, max = maxval, 
   msgs = { 'tooshort': (‘message for short length’), 
   'toolong': (‘message for long length)})

RangeValidator- Genellikle RangeField ile birlikte kullanılır. Bir sayısal alanın değerini minimum ve maksimum sınırlar içinde doğrulamak faydalıdır. Hızlı bağlantı ve takım boyu parametreleri için mesajlar özelleştirilebilir.

tw2.core.RangeValidator(min = minval, max = maxval, 
   msgs = { 'tooshort': (‘message for short length’), 
   'toolong': (‘message for long length)})

IntValidator- Bu sınıf, RangeValidator'dan türetilmiştir. Bu normalde normal bir metin alanındaki girişin tamsayı verileri içerip içermediğini doğrulamak için kullanılır. Minimum ve maksimum limitler ve ayrıca hata mesajları ayarlanabilir. Ek olarak, tamsayı olmayan giriş için hata mesajı 'notint' parametresi olarak belirtilebilir.

tw2.core.IntValidator(msgs = {‘notint’:’Must be Integer’})

OneOfValidator - Bu doğrulayıcı, kullanıcıyı yalnızca listedeki mevcut seçeneklerden bir değer seçmeye zorlar.

tw2.core.OneOfValidator(values = [option1, option2,..], 
   msgs = {‘notinlist’:’Not in List’}}

DateValidator- Kullanıcı girişinin geçerli bir tarih olmasını sağlamak için çok kullanışlıdır. Tarih biçimi (varsayılan YMD'dir) ve hata mesajı özelleştirilebilir. Minimum ve maksimum tarih sınırları da belirtilebilir. DateTimeValidator, DateTime sınıfının nesnesini doğrulamak için de kullanılabilir.

tw2.core.DateValidator(msgs = {format = ’%Y-%m-%d’, 
   'baddatetime': ('baddate', ('Must follow date format $format_str'))}

EmailValidator- Kullanıcı girişini geçerli bir e-posta adresine göre doğrular. Bu sınıf, daha genel bir RegexValidator'dan miras alınır.

tw2.core.EmailValidator(msgs = {'badregex': ('bademail', 
   ('Must be a valid email address')) }

UrlValidator- Bu sınıf da RegexValidator'dan miras alınır. Kullanıcı girişini geçerli bir URL için doğrular.

tw2.core.UrlValidator(msgs = {'badregex': ('badurl', ('Must be a valid URL’)) }

MatchValidator- Bir alanın değerinin diğeriyle eşleşip eşleşmediğini onaylar. Bu, özellikle kullanıcının bir şifre alanı seçmesi ve onaylaması gerektiğinde kullanışlıdır. MatchValidator'ın tipik kullanımı aşağıda gösterilmiştir -

import tw2.core as twc
import tw2.forms as twf
  
  class AdmissionForm(twf.Form):
      class child(twf.TableLayout):
         validator = twc.MatchValidator('pw', 'pwconfirm')
         pw = twf.PasswordField()
         pwconfirm = twf.PasswordField()

Kontrollerden herhangi biri başarılı olursa, doğrulamanın başarılı olmasının istendiği bir bileşik doğrulayıcı inşa etmek de mümkündür. Diğer durumlarda, yalnızca giriş tüm kontrolleri geçerse doğrulamanın başarılı olmasını isteyebilirsiniz. Bunun için tw2.core, genişletilebilir CompoundValidator'ın alt sınıfları olan Herhangi Biri ve Tümü doğrulayıcıları sağlar.

TurboGears, bilgileri kullanıcıya rahatsız edici olmayan bir şekilde bildirmek için çok uygun bir mesajlaşma sistemi sağlar. Tg modülündeki TGFlash sınıfı, düz bir tanımlama bilgisinde saklanan yanıp sönen mesajlar için destek sağlar. Bu sınıf, sunucu tarafında ve istemci tarafında JavaScript aracılığıyla flash mesajların alınmasını destekler.

render()Python'dan kullanıldığında TGFlash sınıfının yöntemi, bir flash mesaj oluşturmak için şablondan çağrılabilir. JavaScript'te kullanılıyorsa, bir WebFlash nesnesi sağlar. Ortaya çıkarırpayload() ve render() Geçerli flash iletiyi getirme ve JavaScript'ten oluşturma yöntemleri.

Bir TurboGears projesi 'hızlı başlangıç' kullanılarak oluşturulduğunda, bir Master.html şablonuna sahiptir. Bu flash nesnesinin bir değişkeninin tanımını içerir. Denetleyiciden alınan bu flash mesajın içeriği, bu şablondaki işaretli yer tutucunun yerini alır.

<py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
   <div py:if = "flash" py:replace = "Markup(flash)" />
</py:with>

tg.flash_obj işlenmiş herhangi bir şablonun içinde bulunan WebFlash nesnesidir. master.htmlşablonu. Bu nesne, mevcut flaş mesajının alınmasına ve görüntülenmesine izin verir.

Flash mesajlar, (varsayılan olarak adı webflash olan) bir çerezde saklanır. tg.flash()yöntem. Mesaj ve durum parametreleri daha sonra ona aktarılır.

tg.flash('Message', 'status')

Flash olarak adlandırılan yöntem bir yönlendirme gerçekleştirirse, flash yönlendirilen sayfanın içinde görünür olacaktır. Yöntem doğrudan bir şablonu ortaya çıkarırsa, flaş şablonun içinde görünür olacaktır.

Flash mesajın görünümü, durum koduna CSS stili uygulanarak özelleştirilebilir. 'Hızlı başlangıç' projesi, public / css / style.css stil sayfası tarafından özelleştirilmiş hata, uyarı, bilgi ve tamam durum kodlarını içerir. Stiller içeren daha fazla durum kodu da eklenebilir.

#flash > .warning {
   color: #c09853;
   background-color: #fcf8e3;
   border-color: #fbeed5;
}

#flash > .ok {
   color: #468847;
   background-color: #dff0d8;
   border-color: #d6e9c6;
}

#flash > .error {
   color: #b94a48;
   background-color: #f2dede;
   border-color: #eed3d7;
}

#flash > .info {
   color: #3a87ad;
   background-color: #d9edf7;
   border-color: #bce8f1;
}

Bu harici stil sayfasının şablona dahil edilmesi gerekiyor -

<link rel = "stylesheet" type = "text/css" media = "screen" 
   href = "${tg.url('/css/style.css')}" />

Herhangi bir Flash mesaj desteğinin konfigürasyonu, TGFlash nesnesinin configure () yöntemi veya app_cfg.py (config klasöründe) için parametreler ayarlanarak elde edilebilir. Yapılandırılabilir parametreler şunlardır:

Sr.No. Parametreler ve Açıklama
1

flash.cookie_name

Flash mesajları saklamak için kullanılan çerezin adı. Varsayılanwebflash.

2

flash.default_status

Belirtilmemişse varsayılan mesaj durumu (varsayılan olarak tamam)

3

flash.template

Olarak kullanılır flash template işlendiğinde.

4

flash.allow_html

Döner on/off escaping in flash messages, varsayılan olarak HTML'ye izin verilmez.

5

flash.js_call

Flash'ı JavaScript'ten görüntülerken çalıştırılacak olan JavaScript kodu. Varsayılanwebflash.render()

6

flash.js_template

string.Template Flash mesajlar için tam JavaScript desteğini değiştirmek için kullanılan örnek.

  • pop_payload() - işlev fetches current flash message, statusve ilgili bilgiler. Flash mesajı almak çerezi silecektir.

  • render(container_id, use_js=True) - Flash mesajını şablon içinde işleyin veya onlar için Javascript desteği sağlayın.

  • container_id , mesajların görüntüleneceği DIV'dir, use_js ise flash'ı HTML olarak veya JavaScript kullanımı için işleme arasında geçiş yapar.

  • status - Sadece mevcut flash durumunu alın, flash durumunu almak çerezi siler.

  • message - Sadece güncel flash mesajı alın, flash mesajı aldığınızda çerez silinir.

Basit Bir Hızlı Mesaj Nasıl Yapılır?

Aşağıdaki örnekte, kök denetleyici sınıfında bir flash () yöntemi sağlanmıştır. Açığa çıkan şablon flash.html'de işlenen bir flash () mesajı çağırır.

from hello.lib.base import BaseController
from tg import expose, flash, redirect, request

class RootController(BaseController):
   @expose('hello.templates.flash')
   def flash(self, user = None):
      
      if user:
         flash(message = "Welcome "+user,status = "ok")
      else:
         flash(message = "Welcome Guest",status = "info")
      return {}

Yapma kodu flash.html şablonlar klasöründe aşağıdaki gibidir

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   xmlns:xi = "http://www.w3.org/2001/XInclude">

   <head>
      <title>TurboGears 2.3: Flash messages>/title>
      <link rel = "stylesheet" type = "text/css" media = "screen"
         href = "${tg.url('/css/style.css')}" />
			
      <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
         <div py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
		
   </head>

   <body>
      <h2>Hello TurboGears</h2>
   </body>
	
</html>

Sunucuyu başlatın ve girin http://localhost:8080/flash?user=MVL tarayıcıda

URL'yi değiştir http://localhost:8080/flash ve style.css'deki tanıma göre farklı biçimlendirilmiş flash mesajı görün

Genellikle, bir kullanıcının tarayıcısına eklenmiş basit tarama verilerini tutmak gerekir. Seanslar en yaygın kullanılan tekniktir. Oturum, disk dosyası veya veritabanı gibi daha kalıcı bir biçimde depolanması gerekmeyen verileri temsil eder.

Ancak, TurboGears'taki oturum verileri dosya sistemi, veritabanı veya karma tanımlama bilgisi değerleri ile yedeklenebilir. Çerezlerde küçük bir miktar oturum verisi saklanır, ancak daha büyük hacimli oturum verileri için MemCache kullanılır.

MemCache, sistem düzeyinde bir arka plan programıdır. Önbelleğe alınmış verilere hızlı erişim sağlar ve son derece ölçeklenebilir. Ancak, yalnızca güvenli sunucularda kullanılmak üzere tasarlanmıştır ve bu nedenle sysadmin tarafından bakımı ve güvenliği sağlanmalıdır.

Oturum Yönetiminde Beher

TurboGears, oturum yönetimi için Beaker'ı kullanır. Gearbox tarafından hızlı başlatılan bir proje, varsayılan olarak oturum verilerini depolamak için karma tanımlama bilgilerini kullanacak şekilde yapılandırılır.

Bir istemci her bağlandığında, oturum ara yazılımı (Beaker), yapılandırma dosyasında tanımlanan çerez adını kullanarak çerezi inceleyecektir. Tanımlama bilgisi bulunmazsa, tarayıcıda ayarlanacaktır. Sonraki tüm ziyaretlerde, ara katman yazılımı çerezi bulacak ve onu kullanacaktır.

Oturum yönetimini etkinleştirmek için, import ifadesi izlenerek oturum sınıfı projeye dahil edilmelidir -

from tg import session

Verileri bir oturum değişkenine kaydetmek için -

session[‘key’] = value
session.save()

Oturum değişkenini almak için -

return session[‘key’]

Anahtarlarınızın o oturumda saklanması için oturumu açıkça kaydetmeniz gerektiğini unutmayın.

delete() oturum nesnesinin yöntemi tüm kullanıcı oturumlarını silecek -

session.delete()

Herhangi bir üretim ortamındaki tüm kullanıcı oturumlarını silmek alışılmış bir şey olmasa da, bunu genellikle kullanılabilirlik veya işlevsel testler yapıldıktan sonra temizlemek için yaparsınız.

Aşağıda, oturumları göstermek için basit bir örnek verilmiştir. RootController sınıfında birsetsession() oturum değişkenini belirleyen yöntem.

from hello.lib.base import BaseController
from tg import expose, session
class RootController(BaseController):
   
   @expose()
   def setsession(self):
      session['user'] = 'MVL'
      session.save()
      
      str = "<b>sessionVariable set to "+session['user'] 
      str = str+"<br><a href = '/getsession'>click here to retrieve</a></b>"
      return str
   
   @expose()
   def getsession(self):
      return "<b>value of session variable retrieved " +session['user'] +"</b>"

Giriş http://localhost:8080/setsession

Tarayıcıdaki bir bağlantı, http://localhost:8080/getsession hangi oturum değişkenini alır ve görüntüler -

Bir web uygulamasının performansını artırmak için, özellikle uzun işlemlerle ilgiliyse, önbelleğe alma teknikleri kullanılır. TurboGears iki tür önbelleğe alma tekniği sağlar -

Whole-page Caching

Kullanıcının tarayıcısını veya bir ara proxy sunucusunun (Squid gibi) isteği durdurmasını ve dosyanın önbelleğe alınmış bir kopyasını döndürmesini sağlayarak sunucuya yönelik tüm istekleri önlemek için HTTP protokol düzeyinde çalışır.

Application-level Caching

Bu, uygulama sunucusunda hesaplanan değerleri, genellikle karmaşık veritabanı sorgularının sonuçlarını önbelleğe almak için çalışır, böylece gelecekteki istekler, değerleri yeniden hesaplama ihtiyacını ortadan kaldırabilir. Web uygulamaları için, uygulama düzeyinde önbelleğe alma, karmaşık sorguların sonuçlarını önbelleğe almak için esnek bir yol sağlar, böylece belirli bir denetleyici yönteminin toplam yükü, birkaç kullanıcıya özgü veya duruma özgü sorgulara ve bir şablonun işleme ek yüküne indirilebilir. .

Uygulama düzeyinde Önbelleğe Alma

Daha önce de belirtildiği gibi, 'hızlı başlatılan' TurboGears projesi, önbelleğe alma desteği için Beaker paketini etkinleştirmek üzere yapılandırılmıştır. Beaker, önbellek depolaması için kullanılan aşağıdaki arka uçları destekler -

  • memory- İşlem başına depolama için kullanılır. Son derece hızlıdır.

  • filesystem - işlem başına depolama ve çok işlemli.

  • DBM database - işlem başına, çok işlemli, oldukça hızlı.

  • SQLAlchemy database- veritabanı sunucusu başına depolama. Yukarıda verilen seçeneklere kıyasla daha yavaş.

  • Memcached - çok sunuculu bellek tabanlı önbellek.

Denetleyici Önbelleğe Alma

Hızlı denetleyici önbelleğe almak için, bir cached()dekoratör mevcuttur. Denetleyici gövdesinin tamamı, çeşitli istek parametrelerine bağlı olarak önbelleğe alınır. Tanımıtg.decorators.cached() dekoratör aşağıdaki gibidir

tg.decorators.cached(key, expire, type, 
   query-args, cache_headers, invalidate_on_startup, cache_response)

Parametrelerin açıklaması aşağıdaki gibidir -

Sr.No. Parametreler ve Açıklama
1

key

Önbellek anahtarını oluşturmak için kullanılan denetleyici parametrelerini belirtir.

2

expire

Önbelleğin süresi dolmadan önce saniye cinsinden süre, Varsayılan "hiçbir zaman" dır.

3

Type

dbm, memory, file, memcached veya None.

4

cache_headers

Yanıt başlıklarını gösteren bir dizi başlık adı.

5

invalidate_on_startup

True ise, uygulama her başladığında veya yeniden başlatıldığında önbellek geçersiz kılınır.

6

cache_response

yanıt önbelleğe alınmalı veya alınmamalıdır, varsayılan olarak True.

Aşağıda bir denetleyici önbelleğe alma örneği verilmiştir -

@cached(expire = 100, type = 'memory')
@expose()
def simple(self):
   return "This is a cached controller!"

Şablon Düzeyinde Önbelleğe Alma

Genshi şablon motoru, içeriği değişmemişse şablonu bir önbellekten alır. Bu önbelleğin varsayılan boyutu 25'tir. Varsayılan olarak, şablonların otomatik olarak yeniden yüklenmesi doğrudur. Performansı artırmak için aşağıdaki ayarlar yapılabilir.app_cfg.py -

[app:main]
genshi.max_cache_size = 100
auto_reload_templates = false

Bir şablonu önbelleğe almak için, tg_cache önbelleğe alınmış şablonu oluşturan denetleyiciden seçenek.

Tg_cache, aşağıdaki anahtarları kabul eden bir sözlüktür -

  • key - Önbellek anahtarı. Default: Yok.

  • expire - önbelleğin ne kadar süre hayatta kalması gerektiği. Default: hiçbir zaman tükenmez

  • type - bellek, dbm, memcached. Default: dbm.

Aşağıdaki örnek, şablon önbelleğe almayı gösterir -

@expose(hello.templates.user')
def user(self, username):
   return dict(user = username, tg_cache = dict(key = user, expire = 900))

Herhangi bir ilişkisel veritabanı üzerinde CRUD işlemleri gerçekleştirmek için TurboGears uygulamasında SQL kullanmak mümkün olsa da, SQLAlchemy kullanılması tavsiye edilir; Python araç seti, uygulama geliştiricilerine SQL'in tam gücünü ve esnekliğini sağlayan güçlü bir Nesne İlişkisi Eşleştiricisidir. TurboGears, SQLAlchemy aracılığıyla SQL tabanlı veritabanları için desteğe ek olarak, Ming üzerinden MongoDB veritabanını da destekler. Bu bölümde, SQLAlchemy'nin işlevselliği tartışılmaktadır.

ORM (Object Relational Mapping) nedir?

Çoğu programlama dili platformu nesne yönelimlidir. RDBMS sunucularındaki veriler ise tablolar olarak saklanır. Nesne ilişkisi eşleme, nesne parametrelerini temeldeki RDBMS tablo yapısına eşleme tekniğidir. ORM API, ham SQL ifadeleri yazmak zorunda kalmadan CRUD işlemlerini gerçekleştirmek için yöntemler sağlar.

Dişli kutusu araç setinden 'hızlı başlangıç' komutu kullanılarak bir TurboGears projesi oluşturulduğunda, SQLAlchemy desteği aşağıdaki yapılandırma ayarlarıyla varsayılan olarak etkinleştirilir -

config['use_sqlalchemy'] = True
config['sqlalchemy.url'] = 'sqlite:///devdata.db'

'Hızlı başlatılan' proje aynı zamanda kendi içinde bir model paketi oluşturur. Örneğin, bir 'Merhaba' projesinde Merhaba \ merhaba \ modeli olacaktır. Bu pakette aşağıdaki dosyalar oluşturulur -

  • __init__.py- Burası veritabanı erişiminin ayarlandığı yerdir. Uygulamanın model nesneleri bu modülde içe aktarılır. Ayrıca bir DBSession - global bir oturum yöneticisi ve ayrıca tüm model sınıfları için temel bir sınıf olan DeclarativeBase vardır.

  • auth.py- Kimlik doğrulama yığını tarafından kullanılan modellerin tanımlandığı yer burasıdır. Ek veritabanı modelleri bu pakette ayrı bir modül olarak saklanır ve __init__.py içine eklenir.

Bir öğrenci masası oluşturacak bir öğrenci modeli ekleyelim. sqlite veri tabanı.

Hello\hello\model\student.py

from sqlalchemy import *
from sqlalchemy.orm import mapper, relation, relation, backref
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode, DateTime

from hello.model import DeclarativeBase, metadata, DBSession
from datetime import datetime

class student(DeclarativeBase):
   __tablename__ = 'student'

   uid = Column(Integer, primary_key = True)
   name = Column(Unicode(20), nullable = False, default = '')
   city = Column(Unicode(20), nullable = False, default = '')
   address = Column(Unicode(100), nullable = False, default = '')
   pincode = Column(Unicode(10), nullable = False, default = '')

Şimdi bu modeli şuraya ekle init_model() içeride işlev __init__.py.Bu işlev zaten içinde kimlik doğrulama modelini içeriyor. Öğrenci modelimizi aşağıya ekleyin.

# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student

Modellerin kurulumu sırasında tablonun bazı verilerle başlatılmasını istiyorsanız, bunu websetup paketindeki bootstrap.py'ye ekleyin. Aşağıdaki ifadeleri ekleyinbootstrap() işlevi.

s1 = model.student()
s1.name = 'M.V.Lathkar'
s1.city = 'Nanded'
s1.address = 'Shivaji Nagar'
s1.pincode = '431602'

model.DBSession.add(s1)
model.DBSession.flush()
transaction.commit()

Modeller, dişli kutusunun kurulum uygulaması komutu çalıştırılarak başlatılır -

gearbox setup-app

SQLAlchemy'nin Session nesnesi, ORM nesnesinin tüm kalıcılık işlemlerini yönetir.

Aşağıdaki oturum yöntemleri CRUD İşlemlerini gerçekleştirir -

  • DBSession.add(model object) - eşlenen tabloya bir kayıt ekler.

  • DBSession.delete(model object) - tablodan kaydı siler.

  • DBSession.query(model).all() - tablodaki tüm kayıtları alır (bir SELECT sorgusuna karşılık gelir).

Bir filtre özelliği kullanarak, alınan kayıt kümesine filtre uygulayabilirsiniz. Örneğin, öğrenciler tablosunda city = 'Hyderabad' olan kayıtları almak için aşağıdaki ifadeyi kullanın -

DBSession.query(model.student).filter_by(city = ’Hyderabad’).all()

Şimdi, denetleyici URL'leri aracılığıyla modellerle nasıl etkileşim kuracağımızı göreceğiz.

Öncelikle öğrencinin verilerini girmek için bir ToscaWidgets formu tasarlayalım

Hello\hello\controllers.studentform.py

import tw2.core as twc
import tw2.forms as twf

class StudentForm(twf.Form):
   class child(twf.TableLayout):
      name = twf.TextField(size = 20)
      city = twf.TextField()
      address = twf.TextArea("",rows = 5, cols = 30)
      pincode = twf.NumberField()

   action = '/save_record'
   submit = twf.SubmitButton(value = 'Submit')

RootController'da (Hello uygulamasının root.py'si), aşağıdaki '/ add' işlev eşlemesini ekleyin URL -

from hello.controllers.studentform import StudentForm

class RootController(BaseController):
   @expose('hello.templates.studentform')
   def add(self, *args, **kw):
      return dict(page='studentform', form = StudentForm)

Aşağıdaki HTML kodunu farklı kaydedin studentform.html şablonlar klasöründe -

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
   
   <head>
      <title>Student Registration Form</title>
   </head>
   
   <body>
      <div id = "getting_started">
         ${form.display(value = dict(title = 'Enter data'))}
      </div>
   </body>

</html>

Giriş http://localhost:8080/addsunucuyu başlattıktan sonra tarayıcıda. Aşağıdaki Öğrenci bilgi formu tarayıcıda açılacaktır -

Yukarıdaki form şu adrese gönderilmek üzere tasarlanmıştır: ‘/save_record’URL. Dolayısıyla asave_record() fonksiyonun eklenmesi gerekiyor root.pyifşa etmek için. Öğrenci formundaki veriler bu işlev tarafından birdict()nesne. Öğrenci modelinin altında yatan öğrenci tablosuna yeni bir kayıt eklemek için kullanılır.

@expose()
#@validate(form = AdmissionForm, error_handler = index1)

def save_record(self, **kw):
   newstudent = student(name = kw['name'],city = kw['city'],
      address = kw['address'], pincode = kw['pincode'])
   DBSession.add(newstudent)
   flash(message = "new entry added successfully")
   redirect("/listrec")

Başarılı eklemeden sonra tarayıcının şu adrese yeniden yönlendirileceğini lütfen unutmayın: ‘/listrec’ URL. Bu URL, birlistrec() function. Bu işlev, öğrenci tablosundaki tüm kayıtları seçer ve bunları bir dikt nesnesi biçiminde studentlist.html şablonuna gönderir. Bulistrec() işlev aşağıdaki gibidir -

@expose ("hello.templates.studentlist")
def listrec(self):
   entries = DBSession.query(student).all()
   return dict(entries = entries)

Studentlist.html şablonu, py: for yönergesini kullanarak girdiler sözlüğü nesnesini yineler. Studentlist.html şablonu aşağıdaki gibidir -

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/">
   
   <head>
      <link rel = "stylesheet" type = "text/css" media = "screen" 
         href = "${tg.url('/css/style.css')}" />
      <title>Welcome to TurboGears</title>
   </head>
   
   <body>
      <h1>Welcome to TurboGears</h1>
      
      <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
         <div py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
      
      <h2>Current Entries</h2>
      
      <table border = '1'>
         <thead>
            <tr>
               <th>Name</th>
               <th>City</th>
               <th>Address</th>
               <th>Pincode</th>
            </tr>
         </thead>
         
         <tbody>
            <py:for each = "entry in entries">
               <tr>
                  <td>${entry.name}</td> <td>${entry.city}</td>
                  <td>${entry.address}</td> <td>${entry.pincode}</td>
               </tr>
            </py:for>
         </tbody>
         
      </table>
   
   </body>
</html>

Şimdi tekrar ziyaret edin http://localhost:8080/addve verileri forma girin. Gönder düğmesine tıklandığında, tarayıcı öğrenci listesi.html adresine götürür. Ayrıca 'yeni kayıt başarıyla eklendi' mesajı da yanıp sönecektir.

ToscaWidgets, verileri tablo biçiminde sunmanın hızlı bir yolunu sağlayan bir DataGrid denetimi içerir. DataGrid nesnesi aşağıdaki gibi bildirilir -

from tw2.forms import DataGrid
student_grid = DataGrid(fields = [('Name', 'name'),('City', 'city'),
   ('Address','address'), ('PINCODE', 'pincode')])

Şimdi, showgrid () işlevi öğrenci tablosundaki tüm kayıtları alır ve verileri grid.html şablonuna sunar. Önce showgrid () işlevinin kodu ve ardından grid.html kodu aşağıda verilmiştir -

ızgarayı göster()

@expose('hello.templates.grid')
def showgrid(self):
   data = DBSession.query(student).all()
   return dict(page = 'grid', grid = student_grid, data = data)

grid.html

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
   
   <head>
      <title>Student Registration Form</title>
   </head>
   
   <body>
      <div id = "getting_started">
         <div>${grid.display(value = data)}</div>
      </div>
   </body>

</html>

Aşağıdaki tablo verileri ne zaman görüntülenecektir http://localhost:8080/showlist Tarayıcıya URL girilir -

TurboGears, sayfalardaki çıktıyı bölmek için paginate () adında kullanışlı bir dekoratör sağlar. Bu dekoratör expose () dekoratörüyle birleştirilir. @Paginate () dekoratörü, sorgu sonucunun sözlük nesnesini bağımsız değişken olarak alır. Ek olarak, sayfa başına kayıt sayısı, items_per_page özniteliğinin değerine göre belirlenir. Paginate işlevini tg.decorators'tan kodunuza aktardığınızdan emin olun.

Root.py içindeki listrec () işlevini aşağıdaki gibi yeniden yazın -

from tg.decorators import paginate
class RootController(BaseController):
   @expose ("hello.templates.studentlist")
   @paginate("entries", items_per_page = 3)
	
   def listrec(self):
      entries = DBSession.query(student).all()
      return dict(entries = entries)

Sayfa başına öğe sayısı üç olacak şekilde ayarlanmıştır.

Studentlist.html şablonunda, py: for yönergesinin altına tmpl_context.paginators.entries.pager () eklenerek sayfada gezinme etkinleştirilir. Bu şablonun kodu aşağıdaki gibi olmalıdır -

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/">
   
   <head>
      <link rel = "stylesheet" type = "text/css" media = "screen" 
         href = "${tg.url('/css/style.css')}" />
      <title>Welcome to TurboGears</title>
   </head>
   
   <body>
      
      <h1>Welcome to TurboGears</h1>
		
      <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
         <div py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
      
      <h2>Current Entries</h2>
		
      <table border = '1'>
         <thead>
            <tr>
               <th>Name</th>
               <th>City</th>
               <th>Address</th>
               <th>Pincode</th>
            </tr>
         </thead>
         
         <tbody>
            <py:for each = "entry in entries">
               <tr>
                  <td>${entry.name}</td> <td>${entry.city}</td>
                  <td>${entry.address}</td> <td>${entry.pincode}</td>
               </tr>
            </py:for>
				
            <div>${tmpl_context.paginators.entries.pager()}</div>
         </tbody>
         
      </table>
   
   </body>

</html>

Giriş http://localhost:8080/listrectarayıcıda. Tablodaki kayıtların ilk sayfası görüntülenir. Bu tablonun üstünde, sayfa numaralarına bağlantılar da görülmektedir.

Datagrid'e Sayfalandırma Desteği Nasıl Eklenir

Datagrid'e sayfalandırma desteği eklemek de mümkündür. Aşağıdaki örnekte, sayfalara ayrılmış datagrid, işlem düğmesini görüntülemek için tasarlanmıştır. Eylem düğmesini etkinleştirmek için datagrid nesnesi aşağıdaki kodla oluşturulur -

student_grid = DataGrid(fields = [('Name', 'name'),('City', 'city'),
   ('Address','address'), ('PINCODE', 'pincode'),
   ('Action', lambda obj:genshi.Markup('<a
      href = "%s">Edit</a>' % url('/edit',
      params = dict(name = obj.name)))) ])

Burada işlem düğmesi, veri ızgarasındaki her satırın ad parametresine bağlıdır.

Yeniden yaz showgrid() aşağıdaki gibi işlev -

@expose('hello.templates.grid')
@paginate("data", items_per_page = 3)

def showgrid(self):
   data = DBSession.query(student).all()
   return dict(page = 'grid', grid = student_grid, data = data)

Tarayıcı, sayfalara ayrılmış datagrid'i aşağıdaki gibi gösterir -

Üçüncü satırdaki Düzenle düğmesini tıkladığınızda, aşağıdaki URL'ye yönlendirilecektir. http://localhost:8080/edit?name=Rajesh+Patil

TurboGears, tgext.crud ve sprox tarafından desteklenen tgext.admin uzantısını sağlar. Bu Sprox, doğrudan veritabanı şemasından web widget'larının oluşturulması için kullanılan bir pakettir. Bu, otomatik olarak basit yönetim sayfaları oluşturmak için kullanılabilir ve yeni hızlı başlatılan uygulamalarda / admin sayfasına güç sağlayan araç setidir.

Varsayılan olarak, yönetici proje modellerinize / __ init__.py içe aktarılan tüm modellere otomatik olarak oluşturulmuş bir erişim sağlayacaktır.

TurboGears Yöneticisi Nasıl Oluşturulur

Varsayılan TurboGears yöneticisi, AdminController sınıfının bir nesnesi olarak oluşturulur -

from tgext.admin.controller import AdminController

class RootController(BaseController):
   admin = AdminController(model, DBSession, config_type = TGAdminConfig)

Bu, varsayılan TurboGears yönetici yapılandırmasına sahip tüm modeller için bir yönetici oluşturur.

Yönetici aracılığıyla, kurulum aşamasında bir kullanıcı oluşturulmuştur. Şimdi, TurboGears Yöneticisine şu adresten erişmek mümkündür:http://localhost:8080/adminBu sayfaya ilk erişildiğinde kimlik doğrulaması istenecektir. Setup-app komutunun bizim için oluşturduğu kullanıcının kullanıcı adını ve şifresini girebilirsiniz -

Username: manager
Password: managepass

Hızlı başlatılan projede oturum açmak için, aşağıdaki işlevleri RootController sınıfına ekleyin (denetleyiciler / root.py).

from hello.lib.base import BaseController
from tg import expose, flash, redirect, request,url, lurl
from tg import redirect, validate
from hello import model
from hello.model import DBSession
from tgext.admin.tgadminconfig import BootstrapTGAdminConfig as TGAdminConfig
from tgext.admin.controller import AdminController
from tg.exceptions import HTTPFound

class RootController(BaseController):
   admin = AdminController(model, DBSession, config_type =  TGAdminConfig)
   
   @expose('hello.templates.index')
   def index(self):
      return dict(page = 'index')
   
   @expose('hello.templates.login')
   def login(self, came_from = lurl('/'), failure = None,    login = ''):
	
      if failure is not None:
         if failure == 'user-not-found':
            flash(_('User not found'), 'error')
         elif failure == 'invalid-password':
            flash(_('Invalid Password'), 'error')
			
      login_counter = request.environ.get('repoze.who.logins', 0)
		
      if failure is None and login_counter > 0:
         flash(_('Wrong credentials'), 'warning')
		 
      return dict(page = 'login', login_counter = str(login_counter), 
         came_from = came_from, login = login)
   @expose()
	
   def post_login(self, came_from = lurl('/')):
      if not request.identity:
         
         login_counter = request.environ.get('repoze.who.logins', 0) + 1
            redirect('/login', params = dict(came_from = came_from,
            __logins = login_counter))
		
         userid = request.identity['repoze.who.userid']
         flash(('Welcome back, %s!') % userid)
			
         return HTTPFound(location = came_from)

Sunucuyu başlattıktan sonra ve adresini ziyaret ederek 'hızlı başlangıç' uygulamasına giriş yapın. http://localhost:8080/loginve sonra yukarıda gösterildiği gibi yönetici kimlik bilgilerini girin. Tarayıcı, aşağıda gösterilene benzer bir yönetici sayfası görüntüleyecektir -

Sayfa, bu uygulamada oluşturulan tüm modelleri gösterir. Girdilerin listesini görmek için herhangi bir modeli tıklayabilirsiniz -

Bu datagrid'in üstündeki 'New' butonu kaydın eklenmesine izin verir. Benzer şekilde, bir kaydı düzenlemek ve silmek için eylem düğmeleri de bu datagrid'in eylemler sütununda sağlanır. Kayıtları koşullu olarak seçmek için bir arama kutusu da görüntülenir.

Yetkilendirme ve kimlik doğrulama desteği varsayılan olarak etkinleştirilmiş olan dişli kutusu araç setinin hızlı başlangıç ​​ve kurulum uygulaması seçenekleriyle bir TurboGears uygulaması oluşturulur. Auth.py'de bildirilen modeller, bootstrap.py'de atanan değerlere göre ayarlanır ve başlatılır.

Aşağıdaki modeller auth.py'de bildirilmiştir -

Kullanıcı Modeli

Kullanıcı modeli, bir tg_user tablosunun tasarımını içerir. Bu tablo, repose.who paketi tarafından kullanılır. Bu repose.who paketi, WSGI uygulamaları için hem güçlü hem de genişletilebilir bir kimlik doğrulama kitaplığıdır. Bir kullanıcı modelinin yapısı aşağıdaki gibidir -

class User(DeclarativeBase):

"""
   __tablename__ = 'tg_user'
   
   user_id = Column(Integer, autoincrement = True, primary_key=True)
   user_name = Column(Unicode(16), unique = True, nullable = False)
   email_address = Column(Unicode(255), unique = True,nullable=False)
                                             
   display_name = Column(Unicode(255))
   _password = Column('password', Unicode(128))
   created = Column(DateTime, default = datetime.now)

Bu grup modeli tg_group tablosu tanımını içerir. Tanımı, auth.py'de aşağıdaki gibi verilmiştir -

class Group(DeclarativeBase):
   __tablename__ = 'tg_group'
   
   group_id = Column(Integer, autoincrement = True,primary_key = True)
   group_name = Column(Unicode(16),unique = True,nullable = False)
   display_name = Column(Unicode(255))
   created = Column(DateTime, default = datetime.now)

İzin tanımını içeren başka bir model izni de ayarlanır.

class Permission(DeclarativeBase):
   __tablename__ = 'tg_permission'
   
   permission_id = Column(Integer,autoincrement = True,primary_key = True)
   permission_name = Column(Unicode(63), unique = True, nullable = False)
   description = Column(Unicode(255))

Modellerin kurulumu sırasında, bu tablolara aşağıdaki veriler eklenir -

u = model.User()
u.user_name = 'manager'
u.display_name = 'Example manager'
u.email_address = '[email protected]'
u.password = 'managepass'

model.DBSession.add(u)
g = model.Group()
g.group_name = 'managers'
g.display_name = 'Managers Group'
g.users.append(u)

model.DBSession.add(g)
p = model.Permission()
p.permission_name = 'manage'
p.description = 'This permission gives an administrative right'
p.groups.append(g)

model.DBSession.add(p)
u1 = model.User()
u1.user_name = 'editor'
u1.display_name = 'Example editor'
u1.email_address = '[email protected]'
u1.password = 'editpass'

model.DBSession.add(u1)

Dayanak Modeli

Tg paketindeki yüklemler modülü, yüklem denetleyicileri için tanımları içerir. Koşul, kullanıcının istenen kaynağa erişebilmesi için karşılanması gereken bir koşuldur. Böyle bir yüklem veya koşul, daha fazla yüklemden oluşabilir - bunlara bileşik yüklemler denir. Eylem denetleyicileri veya denetleyiciler, ister tek ister bileşik olsun, yalnızca bir koşula sahip olabilir.

Bir kullanıcı oturum açmamışsa veya uygun izinlere sahip değilse, bu doğrulama denetleyicisi, kullanıcının oturum açmasına izin veren oturum açma sayfasını görüntülemek için repoze.who ara yazılımı tarafından yakalanan bir 401 (HTTP Yetkilendirilmemiş) atar ve Kullanıcı, tamamlandığında uygun sayfaya geri döner.

Tg.predicates modülünde tanımlanan farklı koşullar veya yüklemler şunlardır:

Sr.No. tg.predicates modülü ve açıklaması
1

All

Belirtilen tüm koşulların karşılanıp karşılanmadığını kontrol edin

2

Any

Belirtilen koşullardan en az birinin karşılanıp karşılanmadığını kontrol edin

3

is_user

Kimliği doğrulanan kullanıcının kullanıcı adının belirtilen ad olduğunu kontrol edin

4

in_group

Kullanıcının belirli bir gruba ait olduğunu kontrol edin.

5

in_all_groups

Kullanıcının belirtilen tüm gruplara ait olduğunu kontrol edin.

6

in_any_group

Kullanıcının belirtilen gruplardan en az birine ait olduğunu kontrol edin.

7

is_anonymous

Mevcut kullanıcının anonim olup olmadığını kontrol edin.

8

has_permission

Mevcut kullanıcının belirtilen izne sahip olup olmadığını kontrol edin.

9

has_all_permissions

Geçerli kullanıcıya belirtilen tüm izinlerin verildiğini kontrol edin.

10

has_any_permission

Kullanıcının belirtilen izinlerden en az birine sahip olup olmadığını kontrol edin.

Örneğin, bir yükleminiz varsa grant access user belonging to customers group, ardından aşağıdaki yerleşik yüklem denetleyicisini kullanabilirsiniz -

from tg.predicates import in_group
p in_group(‘customers’)

Aşağıdaki yüklem denetleyicisi, 'kök' kullanıcıya veya 'yönetme' iznine sahip herhangi birine erişim sağlayacaktır -

from tg.predicates import Any, is_user, has_permission
p = Any(is_user('root'), has_permission('manage'), 
   sg = 'Only administrators can remove blog posts')

TurboGears, MongoDB belge veritabanlarını da destekler. Bir Nesne Belge Eşleyici API'si olan Ming'i kullanır. Ming'in kullanımı SQLAlchemy'ye çok benzer. Ming sorgu dili, SQLAlchemy tabanlı TurboGears projesini Ming'e taşımayı mümkün kılar.

PyMongo nedir

PyMongo, MongoDB ile çalışmak için araçlar içeren bir Python dağıtımıdır. Ming, PyMongo'nun kapsamını genişletiyor -

  • Bildirim Modelleri
  • Şema Doğrulama ve Dönüştürme
  • Şema Evrimi
  • Saf InMemory MongoDB Uygulaması
  • İş Birimi
  • Kimlik Haritası
  • Bire Çok, Çoktan Bire ve Çoktan Çoğa İlişkiler

Öncelikle MongoDB'yi indirip kurmanız gerekiyor. MongoDB'nin en son dağıtımı şuradan indirilebilir:https://www.mongodb.org/downloads

Windows'ta, -dbpath seçeneğini sağlayarak MongoDB sunucusunu başlatın -

C:\mongodb\bin>Mongod --dbpath d:\mongo

D:\mongo folderMongoDB veritabanını depolamak için tasarlanmıştır. Sunucu dinlemeye başlarhttp://localhost:27017. Şimdi MongoDB kabuğunu başlatmak için aşağıdaki komutu kullanın -

C:\mongodb\bin>Mongo

MongoDB ortamımız artık hazır.

Şimdi -ming seçeneğiyle bir TurboGears projesi oluşturun -

gearbox quickstart --ming Hello

Bu hızlı başlatılan proje, SQLAlchemy sürümü için sağlanan gibi bir kimlik doğrulama ve yetkilendirme katmanı sağlayacaktır. Bu uygulama şimdi yerel makinede 27017 numaralı bağlantı noktasındaki bir sunucuya bağlanmayı deneyecek. Proje klasöründeki development.ini dosyası aşağıdaki ayarları içerir -

ming.url = mongodb://localhost:27017/
ming.db = hello

Aşağıdaki komutu kullanarak projeyi kurun -

Python setup.py develop

Proje klasörü, aşağıdaki dosyalara sahip modeller alt klasörünü içerir -

  • __init__.py - Bu nerede databaseerişim ayarlandı. Koleksiyonlarınız olmalıimported into this module. Örneğin, bu pakete öğrenci koleksiyonu ekleyeceğiz.

  • session.py - Bu dosya, session of your database connection. Bunu her beyan etmeniz gerektiğinde içe aktarmanız gerekecekMappedClass oturumu belirtmek için perform queries.

  • auth.py - Eğer varsa, bu dosya oluşturulacak enabled authentication and authorizationhızlı başlangıçta. Üç koleksiyonu tanımlarrepoze.who, daha fazla dayanır: Kullanıcı, Grup ve İzin.

Koleksiyonunuzu Tanımlama

Varsayılan olarak, TurboGears Ming'i bildirimsel bir modda yapılandırır. Bu, SQLAlchemy bildirime dayalı desteğine benzer ve her modelin MappedClass sınıfından miras alması gerekir.

MappedClass, içinde bir __mongometa__ alt sınıfının mevcut olmasını gerektirir, bu da belgeleri depolayan koleksiyonun adı ve belgeleri depolamak için kullanılan oturumla ilgili ayrıntıları sağlar.

MappedClass ayrıca belgedeki alanların tanımını da içerir. Ming'in odm modülü, farklı alan özelliklerinin tanımlarına sahiptir -

  • FieldProperty
  • ForeignIdProperty
  • RelationProperty

ming.schema module aşağıdaki veri türlerini tanımlar -

  • ming.schema.Anything
  • ming.schema.Array
  • ming.schema.Binary
  • ming.schema.Bool
  • ming.schema.Float
  • ming.schema.Int
  • ming.schema.ObjectId
  • ming.schema.Scalar
  • ming.schema.String

Öğrenci koleksiyonunu bu modele eklemek için aşağıdaki kodu öğrenci.py olarak merhaba / modeller klasörüne kaydedin.

Merhaba \ modeller \ öğrenci.py

from ming import schema
from ming.odm import MappedClass
from ming.odm import FieldProperty, ForeignIdProperty
from hello.model import DBSession
   
Class student(MappedClass):
   class __mongometa__:
      session = DBSession
      name = 'student'
      
   _id = FieldProperty(schema.ObjectId)
   name = FieldProperty(schema.String(required = True))
   city = FieldProperty(schema.String(if_missing = ''))
   address = FieldProperty(schema.String(if_missing = ''))
   pincode = FieldProperty(schema.String(if_missing = ''))

Son olarak, bu modeli merhaba \ models \ __ init__.py içine ekleyin

# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student

Bu modelleri kurmak için aşağıdaki dişli kutusu komutunu çalıştırın -

Gearbox setup-app

Sunucuyu aşağıdaki vites kutusu komutuyla başlatın -

Gearbox serve –reload –debug

Bu uygulamanın ana sayfasını açın (http://localhost:8080/)ve yönetici kimlik bilgileriyle oturum açın. Bu uygulamanın yönetici sayfası, ayarlanan modellerin listesini gösterecektir. (yönetici olarak giriş yap, şifre yönetimi)

Koleksiyonların oluşturulması, MongoDB web arayüzünün yanı sıra MongoDB kabuğunda da doğrulanabilir.

ODMSession, aşağıdaki işlevleri kullanarak çeşitli veritabanı işlemlerini gerçekleştirmek için kullanılır -

  • model.query.find()
  • model.query.find_and_modify()
  • model.remove()
  • model.update()
  • model.flush()

ToscoWidget Formu Tasarlama

Şimdi öğrenci verilerini girmek ve öğrenci modelinin altında yatan tabloya eklemek için bir ToscoWidget formu tasarlayacağız.

Studentform.py oluşturma kodu aşağıdadır -

Merhaba \ denetleyiciler \ studentform.py

import tw2.core as twc
import tw2.forms as twf
   
class StudentForm(twf.Form):

   class child(twf.TableLayout):
      name = twf.TextField(size = 20)
      city = twf.TextField()
      address = twf.TextArea("",rows = 5, cols = 30)
      pincode = twf.NumberField()
		
   action = '/save_record'
   submit = twf.SubmitButton(value = 'Submit')

Uygulamanın Rootcontroller '/ add' URL'sinde add () fonksiyonunu çağıran, yukarıda tasarlanan formu tarayıcıda açacaktır. Gönder düğmesi daha sonra save_record () işlevini çağırır. Form verilerini alır ve öğrenci tablosuna kaydeder ve uygulamayı öğrenci listesi şablonunu açığa çıkaran '/ listrec' URL'sine yönlendirir.

Bu etkinlik için root.py aşağıdaki gibidir -

Merhaba / denetleyiciler / root.py

from hello.lib.base import BaseController
from tg import expose, flash, redirect, request,url, lurl
from tg import redirect, validate
from hello import model
from hello.model import DBSession
from hello.model.student import student
   
from hello.controllers.studentform import StudentForm
   
class RootController(BaseController):
   @expose()
   def index(self):
      return "<h1>Hello World</h1>"
         
   @expose ("hello.templates.studentlist")
   def listrec(self):
      entries = student.query.find()
      return dict(entries = entries)
               
   @expose('hello.templates.studentform')
   def add(self, *args, **kw):
      return dict(page = 'studentform', form = StudentForm)
         
   @expose()
   def save_record(self, **kw):
      newstudent = student(name = kw['name'],city = kw['city'],
         address = kw['address'], pincode = kw['pincode'])
      DBSession.flush()
      flash(message = "new entry added successfully")
      redirect("/listrec")

Aşağıdaki şablonlar şablonlar klasöründe oluşturulur -

Merhaba \ templates \ studentform.html

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/" lang = "en">
	
   <head>
      <title>Student Registration Form</title>
   </head>
	

   <body>
      <div id = "getting_started">
         ${form.display(value = dict(title = 'Enter data'))}
      </div>
   </body>
	
</html>

Merhaba \ templates \ studentlist.html

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/">

   <head>
      <link rel = "stylesheet" type = "text/css" media = "screen" 
         href = ${tg.url('/css/style.css')}" /> <title>Welcome to TurboGears</title> </head> <body> <h1>Welcome to TurboGears</h1> <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)"> <div py:if = "flash" py:replace = "Markup(flash)" /> </py:with> <h2>Current Entries</h2> <table border = '1'> <thead> <tr> <th>Name</th> <th>City</th> <th>Address</th> <th>Pincode</th> </tr> </thead> <tbody> <py:for each = "entry in entries"> <tr> <td>${entry.name}</td>
                  <td>${entry.city}</td> <td>${entry.address}</td>
                  <td>${entry.pincode}</td>
               </tr>
            </py:for>
         </tbody>
      </table>
		
   </body>
	
</html>

Sunucuyu yeniden başlatın ve girin http://localhost:8080/add tarayıcıda -

Veri eklendiğinde ve gönder düğmesine her basıldığında, mevcut girişlerin listesi görüntülenecektir.

Gearbox araç takımı, TurboGears uygulamasının yeni bileşenlerini hızlı bir şekilde oluşturmak için çok yararlı olan iskele komutunu içerir. Gearbox'ın quickstart komutu tarafından oluşturulan bir uygulama, model klasöründe (model.py.template), bir şablon klasöründe (template.html.template) ve bir denetleyiciler klasöründe (controller.py.template) bir iskelet şablonuna sahiptir. Bu '.template' dosyaları, bir uygulama için yeni iskeleler oluşturmak için temel olarak kullanılır.

Örneğin, mymodel adında yeni bir model oluşturmak için aşağıdaki komutu çalıştırmanız yeterlidir -

gearbox scaffold model mymodel

Bu komut, içinde tanımlanmış newmodel sınıfı ile model / mymodel.py oluşturacaktır.

# -*- coding: utf-8 -*-
"""Mymodel model module."""
from sqlalchemy import *
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode, DateTime, LargeBinary
from sqlalchemy.orm import relationship, backref
from hello.model import DeclarativeBase, metadata, DBSession

class Mymodel(DeclarativeBase):
   __tablename__ = 'mymodels'
   
   uid = Column(Integer, primary_key = True)
   data = Column(Unicode(255), nullable = False)
   
   user_id = Column(Integer, ForeignKey('tg_user.user_id'), index = True)
   user = relationship('User', uselist = False,
      backref = backref('mymodels',cascade = 'all, delete-orphan'))
   __all__ = ['Mymodel']

Kullanıcılar artık gereksinimlerine göre tablo yapısında değişiklikler yapabilir ve ardından içeriye aktarabilir. model/__init__.py modeli uygulama içinde kullanılabilir hale getirmek için.

Bir model oluşturmak için, onu işleyecek bir kontrolör sınıfı ve bir indeks sayfası aşağıdaki komutla bu üç bileşenin tümü aynı anda oluşturulabilir.

gearbox scaffold model controller template mymodel

Bu komut, MymodelController sınıfının gerektiği gibi tanımlandığı denetleyiciler \ mymodel.py ile sonuçlanacaktır.

# -*- coding: utf-8 -*-
"""Mymodel controller module"""

from tg import expose, redirect, validate, flash, url
# from tg.i18n import ugettext as _
# from tg import predicates

from hello.lib.base import BaseController
# from hello.model import DBSession

class MymodelController(BaseController):
   # Uncomment this line if your controller requires an authenticated user
   # allow_only = predicates.not_anonymous()
   
   @expose('hello.templates.mymodel')
   def index(self, **kw):
      return dict(page = 'mymodel-index')

Bu denetleyiciyi kullanmaya başlamak için, yalnızca bir MymodelController örneğini tanımlamak için uygulamanızın RootController içine monte edin. Bu satırları denetleyiciler \ root.py içine ekleyin -

From hello.controller.mymodel import MymodelController

class RootController(BaseController): mymodel = MymodelController()

Şablonlar klasöründe bir şablon iskele şablonları \ mymodel.html de oluşturulacaktır. '/ Mymodel' URL'si için bir dizin sayfası görevi görecek.

Oluşturulan mymodel.html file şablonlar klasöründe aşağıdaki gibi olacaktır -

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   xmlns:xi = "http://www.w3.org/2001/XInclude">
	
   <xi:include href = "master.html" />
	
   <head>
      <title>Mymodel</title>
   </head>
	
   <body>
      <div class = "row">
         <div class = "col-md-12">
            <h2>Mymodel</h2>
            <p>Template page for Mymodel</p>
         </div>
      </div>
   </body>
	
</html>

TurboGears'ta, mevcut uygulamaların içindeki davranışları eklemenin üç yolu vardır.

  • Hook - Bir olayı tanımlamanın ve kayıtlı dinleyicileri olayların yayınlandığı anda ve ne zaman yayınlanacağını bildirmenin mümkün olduğu bir mekanizmadır.

  • Controller Wrapper- TurboGears ile Denetleyici arasında bulunur, böylece denetleyiciyi bir dekoratör gibi genişletmek mümkündür. Böylece, herhangi bir üçüncü taraf denetleyici uygulamasına eklenebilir.

  • Application Wrapper - Herhangi bir WSGI ara yazılımına benzer, ancak yalnızca TurboGears bağlamında çalışır.

İşte bu bölümde, mevcut bir uygulamada kancaların nasıl kullanılacağını tartışacağız.

Kancalar

Hook'lar, uygulamanın yapılandırma dosyasında kayıtlı olaylardır app_cfg.py. Daha sonra herhangi bir denetleyici, olay dekoratörleri tarafından bu olaylara bağlanır.

Aşağıdaki kancalar TurboGears'ta tanımlanmıştır -

Sr.No. Kancalar ve Açıklama
1

Startup()

yalnızca uygulama geniş, uygulama başladığında çağrılır.

2

shutdown()

Yalnızca uygulama genişliğinde, uygulama çıkıldığında çağrılır.

3

configure_new_app

uygulama yapılandırıcısı tarafından yeni uygulama oluşturuldu.

4

before_config(app)

yalnızca uygulama genelinde, uygulama oluşturduktan hemen sonra, ancak seçenekleri ve ara yazılımları ayarlamadan önce çağrılır

5

after_config(app)

yalnızca uygulama genişliğinde, her şeyi ayarladıktan sonra çağrılır.

6

before_validate

Doğrulama yapılmadan önce çağrıldı

7

before_call

Doğrulamadan sonra, gerçek denetleyici yöntemini çağırmadan önce çağrılır.

8

before_render

Bir denetleyici şablonunu oluşturmadan önce çağrılan çıktı, denetleyici dönüş değeridir.

9

after_render

Bir denetleyici şablonunun işlenmesi tamamlandıktan sonra çağrılır.

Bir Kanca Kaydedin

amacıyla register a Hook, fonksiyonlar oluşturmak app_cfg.py ve sonra aşağıdaki kodu kullanarak bunları kaydedin -

tg.hooks.register(hookane, function, controller)

Aşağıdaki kodda, on_startup, on_shutdown ve before_render kancaları app_cfg.py dosyasında kaydedilir.

def on_startup():
   print 'hello, startup world'
   
def on_shutdown():
   print 'hello, shutdown world'
   
def before_render(remainder, params, output):
   print 'system wide before render'
   
# ... (base_config init code)
tg.hooks.register('startup', on_startup)
tg.hooks.register('shutdown', on_shutdown)
tg.hooks.register('before_render', before_render)

Before_render kancası, Kök denetleyicideki bir denetleyici işlevi ile kaydedilir. Aşağıdaki kodu controllers \ root.py içine ekleyin.

from tg.decorators import before_render

class RootController(BaseController):
   @expose('hello.templates.index')
   @before_render(before_render_cb)
	
   def index(self, *args, **kw):
      return dict(page = 'index')

Uygulama sunulduğunda konsolda başlatma mesajı görüntülenir.

hello, startup world
Starting Standard HTTP server on http://127.0.0.1:8080

Tarayıcıya '/' URL'si girildiğinde, konsolda before_render kancasına karşılık gelen bir mesaj görüntülenir.

system wide before render
Going to render {'page': 'index'}

TurboGears uzantıları şu şekilde tanımlanır: tgext.* package. Bir Gearbox araç seti, örnek bir uzantı oluşturmak için tgext komutu sağlar. Örneğin -

gearbox tgext -n myextension

Bu komut için diğer isteğe bağlı parametreler şunlardır:

  • --author - paket yazarının adı.

  • --email - paket yazarının e-postası.

  • --licence- paket için kullanılan lisans. Varsayılan MIT'dir.

  • --description - Paketin açıklaması.

  • --keywords - Paket anahtar sözcükleri (varsayılan: turbogears2.extension).

Bu, içinde basit bir örnek uzantı bulunan bir tgext.myextension dizini oluşturacaktır.

Run the setup.py dizinin içinde -

Python setup.py install

_init_.py içindeki dosya tgext/myextension klasör şunları içerir -

  • Plugme function - Bu, uzantının giriş noktasıdır.

  • SetupExtension class - uzantı başlatma burada gerçekleşir.

  • On_startup function - sınıfın içinde, sınıf içindeki __call__ işlevine kayıtlı bir kanca bulunur.

Kısa versiyonu tgext\myextension\__init__.py.

from tg import config
from tg import hooks
from tg.configuration import milestones

import logging
log = logging.getLogger('tgext.myextension')

def plugme(configurator, options = None):
   if options is None:
      options = {}
   log.info('Setting up tgext.myextension extension...')
   milestones.config_ready.register(SetupExtension(configurator))
   
   return dict(appid='tgext.myextension')
	
class SetupExtension(object):
   def __init__(self, configurator):
      self.configurator = configurator
      
   def __call__(self):
      log.info('>>> Public files path is %s' % config['paths']['static_files'])
      hooks.register('startup', self.on_startup)
      
   def echo_wrapper_factory(handler, config):
      def echo_wrapper(controller, environ, context):
         log.info('Serving: %s' % context.request.path)
         return handler(controller, environ, context)
      return echo_wrapper
      
   self.configurator.register_wrapper(echo_wrapper_factory)
   
   def on_startup(self):
      log.info('+ Application Running!')

Uzantı yüklendikten sonra, uygulamanın uzantısına aşağıdaki eklemeleri yaparak açın. app_cfg.py yapılandırma dosyası.

from tgext.myextension import plugme

plugme(base_config)

Sunucuyu bir dişli kutusu sunucu komutu kullanarak başlatırsak, yeni kaydedilmiş bir uzantının bildirimi aşağıdaki şekilde konsolda görüntülenebilir -

14:29:13,250 INFO [tgext.myextension] Setting up tgext.myextension extension...
14:29:13,453 INFO [tgext.myextension] >>> Public files path is c:\tghello\hello\hello\public
14:29:13,453 INFO [tgext.myextension] + Application Running!

Starting Standard HTTP server on http://127.0.0.1:8080

Uzantınızın modelleri ve denetleyicileri ortaya çıkarması gerekiyorsa, muhtemelen bir göz atmak istersiniz. Pluggable Applications, özelliklerini genişletmek için diğer uygulamaların içine takılabilen yeniden kullanılabilir Turbogears uygulamaları oluşturmayı amaçlamaktadır.

Takılabilir bir uygulama oluşturmak için aşağıdaki vites kutusu komutunu kullanın -

gearbox quickstart-pluggable plugtest

Bu takılabilir uygulamalar kendi özelliklerini tanımlayabilir -

  • Controllers - uygulama temizlendiğinde otomatik olarak monte edilecektir.

  • Models - takılı uygulamanın içinde ve dışında mevcut olacak.

  • Helpers - bir uygulama şablonundaki 'H' nesnesinde otomatik olarak gösterilebilir.

  • Bootstrap - kurulum uygulaması çağrıldığında yürütülecektir.

  • Statics - kendi özel yollarında mevcut olacak.

Bu eklenti testi uygulamasını kurun ve aşağıdaki değişiklikleri yaparak aynısını app_cfg.py.

from tgext.pluggable import plug
plug(base_config, plugtest)

REST, şu anlama gelir: REsunum STate Transfer. REST, web standartları tabanlı bir mimaridir ve veri iletişimi için HTTP Protokolünü kullanır. Her bileşenin bir kaynak olduğu ve bir kaynağa HTTP standart yöntemleri kullanılarak ortak bir arayüzle erişildiği bir kaynak etrafında döner. REST ilk olarakRoy Fielding in 2000.

RestController nedir

TurboGears'taki RestController, yalnızca URL'ye değil, isteğin yöntemine erişmek için bir mekanizma sağlar. Standart HTTP ifadeleri şunları içerir: GET, POST, PUT ve DELETE. RestController bunları destekler ve ayrıca URL gönderimi için verilerin formlar ve listeler olarak görüntülenmesini kullanıcı için biraz daha kolay hale getiren birkaç kısayol ekler.

RESTful'un TurboGears ile nasıl çalıştığını açıklamak için, bir öğrenci listesini ortaya çıkaran basit bir web hizmeti tanımlayacağız.

Öğrenci modeli kodu aşağıda verilmiştir -

model \ öğrenci.py

# -* - coding: utf-8 -*-
from sqlalchemy import *

from sqlalchemy.orm import mapper, relation, relation, backref
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode, DateTime
from hello.model import DeclarativeBase, metadata, DBSession
from datetime import datetime

class student(DeclarativeBase):
   __tablename__ = 'student'
   
   uid = Column(Integer, primary_key = True)
   name = Column(Unicode(20), nullable = False, default = '')
   city = Column(Unicode(20), nullable = False, default = '')
   address = Column(Unicode(100), nullable = False, default = '')
   pincode = Column(Unicode(10), nullable = False, default = '')

Şimdi RestController'a dayalı bir denetleyici oluşturun ve öğrencilerin listesini json biçiminde listelemek için bir görünüm işlevi sağlayın.

Denetleyiciler \ student.py

from tg import RestController
from tg import expose
from hello import model
from hello.model import DBSession
from hello.model.student import student
from tg.decorators import with_trailing_slash

class StudentController(RestController):
   @expose('json')
   def get_all(self):
      students = DBSession.query(student).all()
      return dict(students=students)

Aşağıdaki satırları dahil ederek bu StudentController'ı uygulamanın RootController'ına bağlayın. root.py -

from hello.controllers.student import StudentController

class RootController(BaseController):

   students = StudentController()

Gitmek http://localhost:8080/students json formatında kodlanmış öğrencilerimizin listesini sağlayacaktır.

Öğrencimizi veritabanına nasıl kaydedeceğimizi tanımlamak için post yöntemini kullanırız. Bu yöntem ne zaman çağrılır http://localhost:8080/student url'ye bir POST isteği kullanılarak erişiliyor -

@expose('json')
def post(self, name, city, address, pincode):
   newstudent = student(name = name, city = city, address = address, pincode = pincode)
   DBSession.add(newstudent)
   DBSession.flush()
   return dict(student = newstudent)

Kullanmak get_one() yöntem, veritabanından bir öğeyi kullanıcıya gösterebiliriz -

@expose('json')
def get_one(self, movie_id):
   newstudent = DBSession.query(student).get(uid)
   return dict(movie = movie)

PUT, mevcut bir kaydı REST kullanarak güncellemek için kullanılan yöntemdir -

@expose('json')
def put(self, name = name, city = city, address =  address, pincode = pincode, **kw):
   newstudent = DBSession.query(student).get(name)
   newstudent.name = name
   newstudent.city = city
   newstudent.address = address
   newstudent.pincode = pincode
   return dict(student = newstudent)

Silme iş atı, post_delete yöntemine eklenir. Burada aslında kaydı veritabanından kaldırıyoruz ve ardından listeleme sayfasına geri yönlendiriyoruz -

@expose('json')
def post_delete(self, uid, **kw):
   newstudent = DBSession.query(student).get(uid)
   DBSession.delete(newstudent)
   return dict(movie = newstudent.uid)

Bir geliştirme ortamından tam teşekküllü bir üretim ortamına geçmek için, uygulamanın gerçek bir web sunucusunda dağıtılması gerekir. Sahip olduklarınıza bağlı olarak, bir TurboGears web uygulamasını dağıtmak için farklı seçenekler mevcuttur.

Mod_wsgi ile Apache

Mod_wsgi, Graham Dumpleton tarafından geliştirilmiş bir Apache modülüdür. WSGI programlarının Apache web sunucusu kullanılarak sunulmasına izin verir.

İlk olarak, henüz yapılmadıysa, platformunuz için Apache 2.X'i kurun. Apache'yi kurduktan sonra mod_wsgi'yi kurun. Sunucuda Python sanal ortamı oluşturun ve etkinleştirin ve içine TurboGears yükleyin.

Uygulamanızı uygulama yöneticisine yükleyin, ardından adlı bir komut dosyası oluşturun app.wsgi.

Apache kurulumunu aşağıdaki gibi yapılandırın -

<VirtualHost *:80>
   ServerName www.site1.com
   WSGIProcessGroup www.site1.com
   WSGIDaemonProcess www.site1.com user = <username> 
      group = www-data threads = 4 python-path = <pythonpath>
   WSGIScriptAlias myapp/app.wsgi
	
   #Serve static files directly without TurboGears
   Alias /images
   Alias /css
   Alias /js
   CustomLog
   ErrorLog
</VirtualHost>

Apache'yi yeniden başlatın

Tür http://www.site1.com/ uygulamaya erişmek için bir tarayıcıda.

Sirk ve Chaussette altında TurboGears

Sirk bir süreç ve soket yöneticisidir. Süreçleri ve soketleri izlemek ve kontrol etmek için kullanılabilir. Chaussette WSGI sunucusuyla eşleştirildiğinde, uygulamanızı dağıtmak ve uygulamalarınızın ihtiyaç duyduğu tüm ilgili işlemleri yönetmek için güçlü bir araç haline gelebilir.

TurboGears - GoogleAppEngine

Python için Google AppEngine SDK'sını aşağıdaki URL'den yükleyin - https://cloud.google.coms

Google AppEngine'i sisteminize yükleyin. Ardından Google Geliştirici konsolunu açın ve Google Hesabınızla oturum açın -https://console.developers.google.com/start

Adlı yeni bir proje oluşturun mytgapp -

Google AppEngine Launcher'ı kullanarak adlı yeni bir uygulama oluşturun mytgapp.

Aşağıdaki dosyalar belirtilen dizinde oluşturulacaktır -

  • app.yaml
  • favicon.ico
  • index.yaml
  • main.py

Varsayılan olarak, oluşturulan uygulama Webapp2 çerçevesine dayanır. Bu bağımlılığı kaldırmak için app.yaml dosyasını düzenleyin ve aşağıdaki bölümü silin -

libraries:
   - name: webapp2
   version: "2.5.2"

Mytgapp adlı bir dizinde geçici bir sanal ortam oluşturun ve TurboGears'ı kurun. İçinde bir TurboGears uygulaması oluşturun. Şimdi düzenlemeye devam edebilirizmain.py AppEngine tarafından uygulamamızı çalıştırmak ve orada bir TurboGears uygulaması yazmak için başlatılan dosya.

Aşağıdaki içerikleri şuraya ekleyin: main.py -

import os
import site
site.addsitedir(os.path.join(os.path.dirname(__file__), 'packages'))
from tg import expose, TGController, AppConfig

class RootController(TGController):
   @expose()
   def index(self):
      return "<h1>Hello World</h1>"
		
config = AppConfig(minimal = True, root_controller = RootController())
app = config.make_wsgi_app()

Şimdi uygulamayı AppEngine Launcher'dan çalıştırın ve uygulamanın localhost üzerinde düzgün çalıştığını görmek için gözat düğmesine tıklayın.

Geliştirici konsolunda zaten mytgapp adlı bir proje oluşturduk. Şimdi Başlatıcı'daki dağıt düğmesine tıklayın. Dağıtım süreci bittikten sonra,http://mytgapp.appspot.com/ başvurumuzu çevrimiçi görüntülemek için ziyaret edin.