Turbogears - Panduan Cepat

Apa itu Kerangka Web?

Kerangka Aplikasi Web atau hanya Kerangka Web mewakili kumpulan pustaka dan modul, yang memungkinkan pengembang aplikasi web untuk menulis aplikasi, tanpa harus memikirkan detail tingkat rendah seperti protokol, manajemen utas, dll.

Apa itu TurboGears?

TurboGears adalah kerangka aplikasi web yang ditulis dengan Python. Awalnya dibuat oleh Kevin Dangoor pada tahun 2005, versi terbarunya TurboGears (ver 2.3.7) dikelola oleh sekelompok pengembang yang dipimpin oleh Mark Ramm dan Florent Aide.

TurboGears mengikuti paradigma Model-View-Controller seperti halnya kebanyakan kerangka web modern seperti Rails, Django, Struts, dll.

Model View Controller

MVC adalah pola desain perangkat lunak untuk mengembangkan aplikasi web. Pola Model View Controller terdiri dari tiga bagian -

  • Model - Tingkat terendah dari pola bertanggung jawab untuk memelihara data.

  • View - Ini bertanggung jawab untuk menampilkan semua atau sebagian data kepada pengguna.

  • Controller - Kode Perangkat Lunak yang mengontrol interaksi antara Model dan Tampilan.

MVC populer karena mengisolasi logika aplikasi dari lapisan antarmuka pengguna dan mendukung pemisahan masalah. Di sini, Pengontrol menerima semua permintaan untuk aplikasi dan kemudian bekerja dengan Model untuk menyiapkan data apa pun yang dibutuhkan oleh Tampilan. Tampilan kemudian menggunakan data yang disiapkan oleh Pengontrol untuk menghasilkan respons akhir yang dapat disajikan. Abstraksi MVC dapat direpresentasikan secara grafis sebagai berikut -

Model

Model bertanggung jawab untuk mengelola data aplikasi. Ini menanggapi permintaan dari tampilan dan juga menanggapi instruksi dari pengontrol untuk memperbarui dirinya sendiri.

Pandangan

Penyajian data dalam format tertentu, dipicu oleh keputusan pengontrol untuk menyajikan data. Mereka adalah sistem template berbasis skrip yang sangat mudah diintegrasikan dengan teknologi AJAX.

Pengendali

Pengontrol bertanggung jawab untuk menanggapi masukan pengguna dan melakukan interaksi pada objek model data. Kontroler menerima input, memvalidasi input dan kemudian melakukan operasi bisnis yang mengubah status model data.

TurboGears dibangun di atas sejumlah pustaka dan alat. Alat-alat ini telah berubah di antara berbagai versi TurboGears. Komponen versi saat ini (ver 2.3.7) didaftar di bawah.

SQLAlchemy

Ini adalah kit SQL open source yang menyediakan pemetaan relasi Objek (ORM) untuk kode Python.

Genshi

Mesin template ini digunakan untuk membangun aplikasi TG front-end. Sistem template web menggabungkan template dengan sumber data tertentu untuk merender halaman web dinamis.

ToscaWidgets

Ini adalah pustaka widget untuk menghasilkan formulir HTML dengan kontrol sisi server. Tosca juga bertindak sebagai middleware untuk terhubung dengan widget dan toolkit JavaScript.

Gearbox

Ini menyediakan sekumpulan perintah untuk mengelola proyek dan aplikasi server TurboGears. Aplikasi TurboGears dapat digunakan di server web yang mendukung WSGI.

Web Server Gateway Interface (WSGI) telah diadopsi sebagai standar untuk pengembangan aplikasi web Python. WSGI adalah spesifikasi untuk antarmuka universal antara web server dan aplikasi web. Paket wsgiref adalah implementasi referensi dari WSGI. Ini digunakan untuk menambahkan dukungan WSGI ke web framework TurboGears web. Modul simple_server dalam paket ini mengimplementasikan server HTTP sederhana yang melayani aplikasi WSGI. Kami akan menggunakannya untuk menguji aplikasi yang dikembangkan selama tutorial ini.

Prasyarat

Python 2.6 atau lebih tinggi. Versi TurboGears sebelumnya tidak kompatibel dengan Python 3.X. Versi terbaru mengklaim bekerja dengan baik pada Python 3.X. Namun, dokumentasi resmi TurboGears masih didasarkan pada lingkungan Python 2.7.

Perintah berikut installs virtualenv -

pip install virtualenv

Perintah ini perlu administratorhak istimewa. Menambahkansudo before pipdi Linux / Mac OS. Jika Anda menggunakan Windows, masuk sebagai Administrator. Di Ubuntu virtualenv dapat diinstal menggunakan manajer paketnya.

Sudo apt-get install virtualenv

Setelah diinstal, lingkungan virtual baru dibuat dalam sebuah folder.

mkdir newproj
cd newproj
virtualenv venv

Untuk mengaktifkan lingkungan terkait, aktif Linux/OS X

venv/bin/activate

di Windows

venv\scripts\activate

Kami sekarang siap install TurboGearsdi lingkungan ini. Instalasi minimal TurboGears dilakukan dengan mengikuti perintah -

pip install TurboGears2

Perintah di atas dapat dijalankan secara langsung tanpa lingkungan virtual untuk instalasi sistem yang luas.

Untuk menginstal TurboGears bersama dengan alat pengembangan, gunakan perintah berikut -

pip install tg.devtools

TurboGears memiliki mode minimal yang memungkinkan untuk membuat aplikasi file tunggal dengan cepat. Contoh dan layanan sederhana dapat dibangun dengan cepat dengan sekumpulan dependensi minimal.

Kelas aplikasi dalam aplikasi TG diwarisi dari TGControllerkelas. Metode di kelas ini tersedia untuk diakses oleh@expose dekorator dari tgmodul. Dalam aplikasi pertama kami,index()metode dipetakan sebagai root dari aplikasi kita. Kelas TGController juga perlu diimpor daritg modul.

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

Selanjutnya, setel konfigurasi aplikasi dan deklarasikan objek aplikasi. AppConfig konstruktor kelas di sini mengambil dua parameter - atribut minimal disetel ke true dan kelas pengontrol.

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

Itu make_wsgi_app() Fungsi di sini membangun objek aplikasi.

Untuk melayani aplikasi ini, sekarang kita perlu menjalankan server HTTP. Seperti yang disebutkan sebelumnya, kami akan menggunakansimple_server modul masuk wsgirefpaket untuk menyiapkan dan memulainya. Modul ini memilikimake_server() metode yang membutuhkan nomor port dan objek aplikasi sebagai argumen.

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

Artinya aplikasi kita akan dilayani di port nomor 8080 localhost.

Berikut ini adalah kode lengkap aplikasi TurboGears pertama kami -

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()

Jalankan skrip di atas dari shell Python.

Python app.py

Memasukkan http://localhost:8080 di bilah alamat browser untuk melihat pesan 'Hello World TurboGears'.

Itu tg.devtoolsdari TurboGears berisi Gearbox. Ini adalah sekumpulan perintah, yang berguna untuk pengelolaan proyek TG yang lebih kompleks. Proyek tumpukan penuh dapat dengan cepat dibuat dengan perintah Gearbox berikut -

gearbox quickstart HelloWorld

Ini akan membuat proyek bernama HelloWorld.

Proyek TurboGears berisi direktori berikut -

  • Config - Di mana pengaturan dan konfigurasi proyek bergantung

  • Controllers - Semua pengontrol proyek, logika aplikasi web

  • i018n - File terjemahan untuk bahasa yang didukung

  • Lib - Fungsi dan kelas utilitas python

  • Model - Model database

  • Public Static Files - CSS, JavaScript, dan gambar

  • Templates - Template diekspos oleh pengontrol kami.

  • Tests - Set Tes selesai.

  • Websetup - Fungsi untuk dieksekusi pada pengaturan aplikasi.

Cara Menginstal proyek

Proyek ini sekarang perlu dipasang. SEBUAHsetup.pysudah tersedia di direktori dasar proyek. Dependensi proyek terinstal ketika skrip ini dijalankan.

Python setup.py develop

Secara default, dependensi berikut diinstal pada saat penyiapan proyek -

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

Setelah instalasi, mulai melayani proyek di server pengembangan dengan mengeluarkan perintah berikut di shell -

Gearbox serve –reload –debug

Ikuti perintah yang disebutkan di atas untuk melayani proyek contoh yang dibuat sebelumnya. Bukahttp://localhost:8080di browser. Contoh aplikasi readymade ini memberikan pengantar singkat tentang framework TurboGears itu sendiri.

Dalam proyek Hello ini, pengontrol default dibuat di direktori pengontrol sebagai Hello/hello/controllers.root.py. Biarkan kamimodify root.py dengan kode berikut -

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"

Setelah aplikasi kerja dasar siap, lebih banyak tampilan dapat ditambahkan di kelas pengontrol. DalamMycontroller kelas di atas, metode baru sayHello()telah ditambahkan. Itu@expose() dekorator menempel /sayHelloURL ke sana. Fungsi ini dirancang untuk menerima nama sebagai parameter dari URL.

Setelah memulai server melalui perintah 'gearbox serve', http://localhost:8080. Pesan Hello World akan ditampilkan di browser, meskipun URL berikut dimasukkan -

http://localhost:8080/

http://localhost:8080/index

Semua URL ini dipetakan ke RootController.index()metode. Kelas ini juga punya_default()metode yang akan dipanggil, setiap kali URL tidak dipetakan ke fungsi tertentu. Respons ke URL dipetakan ke fungsi oleh dekorator @expose ().

Anda dapat mengirim parameter ke fungsi yang terekspos dari URL. Fungsi berikut membaca parameter nama dari URL.

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

Output berikut akan terlihat di browser sebagai respons terhadap URL - http://localhost:8080/?name=MVL

Hello MVL

TurboGears secara otomatis memetakan parameter URL ke argumen fungsi. Kelas RootController kami diwarisi dari BaseController. Ini didefinisikan sebagaibase.py dalam lib folder aplikasi.

Kodenya adalah sebagai berikut -

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__ mengirimkan ke metode Kontroler tempat permintaan diarahkan.

Suatu Peristiwa meskipun konten HTML dapat dikembalikan ke browser, untuk keluaran yang lebih canggih, penggunaan mesin template selalu lebih disukai. Dalam proyek tumpukan penuh 'quickstarted' oleh gearbox, Genshi diaktifkan sebagai perender template default. Dalam aplikasi minimal, bagaimanapun Genshi (atau mesin template lainnya, seperti jinja) perlu diinstal dan diaktifkan. Mesin template Genshi mengizinkan untuk menulis template dalam xhtml murni dan memvalidasinya untuk mendeteksi masalah pada waktu kompilasi dan mencegah penayangan halaman yang rusak.

Templat dirujuk dengan menggunakan notasi titik-titik. Dalam proyek Hello kami, direktori template disediakan untuk menyimpan halaman web template. Karenanyasample.html akan disebut sebagai hello.templates.sample(ekstensi tidak disebutkan). TurboGears membuat template ini melalui dekorator ekspos untuk menghubungkan metode pengontrol dengan itutg.render_template() fungsi.

Fungsi pengontrol terekspos mengembalikan objek kamus Python. Objek kamus ini pada gilirannya diteruskan ke template yang ditautkan. Placeholder di template diisi dengan nilai kamus.

Untuk memulai, mari kita tampilkan halaman web dengan script html biasa. Kontroler yang terbuka mengembalikan anull dictionary object karena kami tidak bermaksud mengirim data apa pun untuk diurai di dalam skrip HTML.

Cara Membuat Contoh HTML

Kami sample.htmldiberikan di bawah ini. Pastikan itu disimpan dalam direktori template proyek.

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

Menambahkan sample() berfungsi di root.py dan mengekspos sample.html melalui itu.

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

Hasil berikut akan ditampilkan di browser saat URL http://localhost:8080/sample dimasukkan setelah memulai server web.

Seperti disebutkan di atas, objek kamus dikirim sebagai kumpulan parameter ke template Genshi. Template ini berisi 'placeholder', yang secara dinamis diisi dengan parameter yang diterima dari pengontrol.

Mari kita ubah sample() berfungsi untuk mengirim objek kamus ke templat sampel.

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

Membuat sample.html di folder template (templates\sample.html)

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

Pada kode HTML di atas, ${person}adalah placeholder. Memasukkanhttp://localhost:8080/sample?name=MVLsebagai URL di browser. URL ini dipetakan kesample()metode di pengontrol root kami. Ini mengembalikan objek kamus. Ini dipilih oleh sample.html halaman template tertaut di direktori template. $ {Person} kemudian diganti dengan MVL di halaman web.

Dimungkinkan juga untuk mengakses data formulir HTML dalam fungsi pengontrol. Formulir HTML digunakan untuk mengirim data formulir.

Protokol Http adalah fondasi komunikasi data di world wide web. Metode pengambilan data yang berbeda dari URL yang ditentukan ditentukan dalam protokol ini. Tabel berikut merangkum berbagai metode http -

Sr.No. Metode & Deskripsi HTTP
1

GET

Mengirim data dalam bentuk tidak terenkripsi ke server. Metode paling umum.

2

HEAD

Sama seperti GET, tetapi tanpa isi respons

3

POST

Digunakan untuk mengirim data formulir HTML ke server. Data yang diterima dengan metode POST tidak di-cache oleh server.

4

PUT

Mengganti semua representasi saat ini dari sumber daya target dengan konten yang diunggah.

5

DELETE

Menghapus semua representasi saat ini dari sumber daya target yang diberikan oleh URL

Membuat Formulir HTML

Mari kita membuat Formulir HTML dan mengirim data formulir ke URL. Simpan skrip berikut sebagai login.html

<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>

Data yang dimasukkan dalam formulir ini harus diserahkan ke ‘/login’ URL. Sekarang buat fungsi pengontrolloginpage() dan tampilkan halaman html di atas padanya.

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

Untuk menerima data formulir, berikan a login()controller, yang memiliki atribut bentuk sebagai parameternya. Sini‘nm’ adalah nama field input teks pada form login, sama digunakan sebagai parameter fungsi login ().

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

Seperti yang terlihat, data yang diterima dari form login dikirim ke template sample.html (digunakan sebelumnya). Ini diurai oleh aGenshi template engine untuk menghasilkan keluaran berikut -

Metode POST

Ketika formulir HTML menggunakan metode POST untuk mengirimkan data ke URL dalam atribut tindakan, data formulir tidak diekspos di URL. Data yang disandikan diterima di adictargumen dengan fungsi pengontrol. **kw Argumen di bawah ini adalah objek kamus yang menyimpan data.

Formulir HTML berisi dua bidang teks masukan.

<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>

Itu marks() pengontrol menerima data formulir dan mengirimkannya ke sample.htmltemplate. Kode untukroot.py adalah sebagai berikut -

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

Terakhir, template sample.html adalah sebagai berikut -

<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>

Mulai server (jika belum berjalan)

Gearbox server –reload –debug

Memasukkan http://localhost::8080/marksform di browser

Itu sample.html akan membuat keluaran berikut -

Genshi adalah bahasa template berbasis XML. Ini mirip denganKid, yang dulunya adalah mesin templat untuk versi TurboGears sebelumnya. Genshi serta Kid terinspirasi oleh bahasa template terkenal lainnya sepertiHSLT, TAL dan PHP.

Template Genshi terdiri dari arahan pemrosesan. Direktif ini adalah elemen dan atribut dalam template. Arahan Genshi didefinisikan dalam namespacehttp://genshi.edgewall.org/. Oleh karena itu namespace ini perlu dideklarasikan di elemen root template.

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

Deklarasi di atas berarti bahwa namespace default disetel ke XHTML dan direktif Genshi memiliki awalan 'py'.

Arahan Genshi

Sejumlah arahan didefinisikan dalam Genshi. Daftar berikut menyebutkan arahan Genshi -

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

Bagian Bersyarat

Genshi menyediakan dua arahan untuk rendering bersyarat dari konten− py: if dan py: pilih.

py: jika

Isi elemen direktif ini akan dirender hanya jika ekspresi dalam if clausemengevaluasi menjadi true. Dengan asumsi bahwa data dalam konteks templat adalah{‘foo’:True, ‘bar’:’Hello’}, petunjuk berikut -

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

akan menghasilkan

Hello

Namun, keluaran ini tidak akan ditampilkan jika ‘foo’ is set to False.

Arahan ini juga dapat digunakan sebagai elemen. Pada kasus ini<py:if> harus ditutup sesuai </py:if>

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

py: pilih

Pemrosesan bersyarat lanjutan dimungkinkan dengan penggunaan py:choose dalam kombinasi dengan py:when dan py:otherwisearahan. Fitur ini mirip denganswitch – case membangun C/C++.

Ekspresi dalam py:choose direktif diperiksa dengan nilai berbeda yang diidentifikasi dengan py:whenalternatif dan konten terkait akan diberikan. Alternatif default dapat diberikan dalam bentukpy:otherwise pengarahan.

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

Contoh berikut menggambarkan penggunaan py:choose dan py:whenarahan. Formulir HTML memposting data ke / menandai URL. Itumarks() fungsi mengalihkan tanda dan hasil dalam bentuk objek kamus ke total.htmltemplate. Tampilan bersyaratresult Pass/Fail dicapai dengan menggunakan py:choose dan py:when arahan.

Script HTML memasukkan tanda (marks.html) adalah sebagai berikut -

<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>

Kode lengkap root.pyadalah sebagai berikut. Itumarks() pengontrol mengirimkan tanda dan hasil ke total.html template -

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

Itu total.html dalam folder templates menerima data kamus dan menguraikannya dalam keluaran html secara kondisional sebagai berikut -

<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>

Mulai server (jika belum berjalan)

Gearbox server –reload –debug

Memasukkan http://localhost::8080/marksform di browser -

Itu total.html akan membuat keluaran berikut -

py: untuk

Elemen di py: untuk direktif diulangi untuk setiap item dalam iterable, biasanya objek Python List. Jikaitems = [1,2,3] hadir dalam konteks template, dapat diulangi dengan mengikuti py: for directive -

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

Output berikut akan dirender -

1
2
3

Contoh berikut menunjukkan data formulir HTML yang dirender dalam total.html template menggunakan py: untuk direktif juga dapat digunakan sebagai berikut -

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

Skrip Formulir HTML

<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>

Itu loop() controller membaca data formulir dan mengirimkannya ke total.template dalam bentuk objek daftar.

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})

Template temp.html menggunakan py: for loop untuk merender konten objek dict dalam bentuk tabel.

<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>

Mulai server (jika belum berjalan)

gearbox server –reload –debug

Memasukkan http://localhost::8080/marksform di browser.

Output berikut akan ditampilkan di browser saat formulir di atas dikirimkan.

py: def

Direktif ini digunakan untuk membuat makro. Makro adalah cuplikan kode template yang dapat digunakan kembali. Sama seperti fungsi Python, ia memiliki nama dan secara opsional dapat memiliki parameter. Output makro ini dapat disisipkan di mana saja di templat.

Direktif py: def mengikuti sintaks berikut -

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

Makro ini dapat dirender dengan nilai variabel ke parameter 'name'.

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

Direktif ini juga dapat digunakan dengan versi sintaks lain sebagai berikut -

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

Dalam contoh berikut, macro() pengontrol dalam root.py mengirimkan a dict objek dengan dua kunci name1 dan name2 ke template macro.html.

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'}

Template macro.html ini berisi definisi makro yang disebut salam. Ini digunakan untuk menghasilkan pesan ucapan untuk data yang diterima dari pengontrol.

<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>

Mulai server menggunakan gearbox

gearbox serve –reload –debug

Panggil pengontrol makro () dengan memasukkan URL berikut di browser -

http://localhost:8080/macro

Output berikut akan ditampilkan di browser -

py: dengan

Direktif ini memungkinkan Anda menetapkan ekspresi ke variabel lokal. Variabel lokal ini membuat ekspresi di dalam menjadi lebih pendek dan lebih efisien.

Dengan asumsi bahwa x = 50 diberikan dalam data konteks untuk template, berikut akan menjadi py: dengan direktif -

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

Ini akan menghasilkan output berikut -

50 50 100

Versi alternatif untuk py: dengan direktif juga tersedia -

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

Dalam contoh berikut, pengontrol makro () mengembalikan objek dict dengan kunci nama, phy, dan matematika.

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}

Template macro.html menambahkan nilai kunci phy dan matematika menggunakan py: dengan direktif.

<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>

Browser akan membuat keluaran berikut sebagai tanggapan atas URL http://localhost:8080/macro

Arahan Manipulasi Struktur

Itu py:attrs direktif menambahkan, mengubah atau menghapus atribut dari elemen.

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

Jika foo = {‘class’:’collapse’} hadir dalam konteks kerangka, yang akan dirender cuplikan di atas.

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

Itu py:content direktif menggantikan konten bersarang apa pun dengan hasil evaluasi ekspresi -

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

Diberikan bar = 'Bye' dalam data konteks, ini akan menghasilkan

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

Itu py:replace direktif menggantikan elemen itu sendiri dengan hasil evaluasi ekspresi -

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

Diberikan bar = 'Bye' dalam data konteks, itu akan menghasilkan

<div>
   Bye
</div>

Isi dari dokumen XML lain (terutama dokumen HTML) dapat dimasukkan dengan menggunakan tag penyertaan di dokumen saat ini. Untuk mengaktifkan penyertaan seperti itu, ruang nama XInclude harus dideklarasikan di elemen akar dokumen HTML.

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

Deklarasi di atas menentukan bahwa termasuk direktif berisi ‘xi’awalan. Untuk menambahkan konten halaman html lain di dokumen saat ini, gunakan perintah xi: include sebagai berikut -

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

Dalam contoh berikut, root.py berisi include () controller, yang memperlihatkan include.html.

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

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

Heading dan Footer HTML

Dalam include.html, ruang nama include dideklarasikan dan konten heading.html dan footer.html ditambahkan. Berikut ini skrip HTML template \ 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>

Berikut adalah template \ heading.html kode -

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

Berikut ini adalah templates \ footer.html

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

Mulai pengembangan menggunakan gearbox dan masuk http://localhost:8080/includedi browser. Output yang diberikan akan seperti yang ditunjukkan di bawah ini -

Dengan cara ini konstruksi tampilan modular dapat dicapai. Jika sumber daya yang disebutkan di xi: termasuk direktif tidak tersedia, kesalahan akan dimunculkan. Dalam kasus seperti itu, sumber daya alternatif dapat dimuat dengan menggunakan xi: fallback.

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

Pencantuman konten dapat dibuat dinamis sebagai atribut href yang dapat memuat ekspresi.

Tambahkan controller berikut di root.py.

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

Simpan kode berikut sebagai ref-include.html di folder template.

<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>

Sebelum memulai server, pastikan folder template memiliki heading.html, main.html dan footer.html. Memasukkanhttp://localhost:8082/refinclude di browser untuk mendapatkan keluaran berikut

Itu @expose()dekorator secara default menampilkan konten html. Namun, ini dapat diatur kejson content type. TurboGears mendukung rendering jsontg.jsonify.JSONEncoder (**kwargs)kelas. Untuk merender data json cukup berikan json sebagai tipe konten untuk mengekspos decorator.

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

Jika URL '/ jsondata' dimasukkan di browser, itu akan merespon dengan menunjukkan -

{"hello": "World"}

jsonp Rendering

jsonp adalah singkatan dari json with padding. Cara kerjanya mirip dengan keluaran json kecuali fakta bahwa ia menyediakan respons aplikasi / javascript dengan panggilan ke fungsi javascript yang menyediakan semua nilai yang dikembalikan oleh pengontrol sebagai argumen fungsi.

Untuk mengaktifkan rendering jsonp, Anda harus menambahkannya terlebih dahulu ke daftar mesin yang diperlukan di dalam aplikasi Anda - config/app_cfg.py -

base_config.renderers.append('jsonp')

Tulis dekorator ekspos Anda sebagai berikut -

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

Saat mengakses / jsonpdata? Callback = callme, Anda harus melihat -

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

Terkadang, aplikasi web mungkin memerlukan struktur URL yang memiliki lebih dari satu level. TurboGears dapat melintasi hierarki objek untuk menemukan metode yang sesuai yang dapat menangani permintaan Anda.

Sebuah proyek 'quickstarted' dengan gearbox memiliki kelas BaseController di folder lib proyek. Ini tersedia sebagai 'Hello / hello / lib / base.py'. Ini berfungsi sebagai kelas dasar untuk semua sub pengontrol. Untuk menambahkan sub level URL dalam aplikasi, desain sub kelas yang disebut BlogController berasal dari BaseController.

BlogController ini memiliki dua fungsi pengontrol, index () dan post (). Keduanya didesain untuk mengekspos template masing-masing, blog.html dan post.html.

Note - Template ini dimasukkan ke dalam sub folder - templates / 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}

Sekarang deklarasikan objek dari kelas ini di kelas RootController (di root.py) sebagai berikut -

class RootController(BaseController):
   blog = BlogController()

Fungsi pengontrol lain untuk URL tingkat atas akan ada di kelas ini seperti sebelumnya.

Saat URL http://localhost:8080/blog/dimasukkan, itu akan dipetakan ke fungsi pengontrol index () di dalam kelas BlogController. Demikian pula,http://localhost:8080/blog/post akan memanggil fungsi post ().

Kode untuk blog.html dan post.html adalah sebagai berikut -

Blog.html

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

post.html

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

Saat URL http://localhost:8080/blog/ dimasukkan, itu akan menghasilkan output berikut -

Saat URL http://localhost:8080/blog/post dimasukkan, itu akan menghasilkan output berikut -

Salah satu aspek paling penting dari aplikasi web apa pun adalah menampilkan antarmuka pengguna untuk pengguna. HTML menyediakan tag <form> yang digunakan untuk mendesain antarmuka. Elemen formulir seperti input teks, radio, pilih, dll. Dapat digunakan dengan tepat. Data yang dimasukkan oleh pengguna dikirimkan dalam bentuk pesan permintaan Http ke skrip sisi server dengan metode GET atau POST.

Skrip sisi server harus membuat ulang elemen formulir dari data permintaan http. Jadi dalam efek ini, elemen formulir harus didefinisikan dua kali - sekali dalam HTML dan sekali lagi dalam skrip sisi server.

Kerugian lain dari menggunakan bentuk HTML adalah sulit (jika bukan tidak mungkin) untuk merender elemen formulir secara dinamis. HTML itu sendiri tidak menyediakan cara untuk memvalidasi masukan pengguna.

ToscaWidgets2

TurboGears mengandalkan ToscaWidgets2, pustaka validasi dan rendering formulir yang fleksibel. Dengan menggunakan ToscaWidgets, kita dapat menentukan bidang formulir dalam skrip Python kita dan membuatnya menggunakan template HTML. Dimungkinkan juga untuk menerapkan validasi ke bidang tw2.

Perpustakaan ToscaWidgets adalah kumpulan dari banyak modul. Beberapa modul penting tercantum di bawah ini -

  • tw2.core- Ini menyediakan fungsionalitas inti. Widget dalam modul ini tidak dimaksudkan untuk tersedia bagi pengguna akhir.

  • tw2.forms- Ini adalah perpustakaan bentuk dasar. Ini berisi widget untuk bidang, kumpulan bidang, dan formulir.

  • tw2.dynforms - Ini berisi fungsionalitas formulir dinamis.

  • tw2.sqla - Ini adalah antarmuka untuk database SQLAlchemy.

tw2.forms

Ini berisi kelas Formulir, yang bertindak sebagai dasar untuk formulir kustom. Ada kelas TableForm yang berguna dalam merender bidang dalam tabel dua kolom. ListForm menyajikan bidangnya dalam daftar yang tidak berurutan.

Sr.No. Bidang & Deskripsi
1

TextField

Bidang input teks satu baris

2

TextArea

Bidang masukan teks multi-baris

3

CheckBox

Menyajikan kotak persegi panjang yang dapat dicentang dengan label

4

CheckBoxList

Kotak centang grup pf multi-pilih

5

RadioButton

Tombol sakelar untuk memilih / batal memilih

6

RadioButtonList

Grup tombol Radio yang saling eksklusif

7

PasswordField

Mirip dengan Textfield tetapi tombol input tidak ditampilkan

8

CalendarDatePicker

Memungkinkan pengguna memilih tanggal

9

SubmitButton

Tombol untuk mengirimkan formulir

10

ImageButton

Tombol yang dapat diklik dengan gambar di atas

11

SingleSelectField

Memungkinkan pemilihan item tunggal dari daftar

12

MultipleSelectField

Memungkinkan pemilihan beberapa item dari daftar

13

FileField

Bidang untuk mengunggah file

14

EmailField

Bidang masukan email

15

URLField

Bidang masukan untuk memasukkan URL

16

NumberField

Sebuah spinbox nomor

17

RangeField

Penggeser angka

Dalam contoh berikut, formulir yang menggunakan beberapa widget ini dibuat. Meskipun sebagian besar widget ini ditentukan dalam tw2.forms, CalendarDateField ditentukan dalam modul tw2.Dynforms. Oleh karena itu kedua modul ini bersama dengan tw2.core diimpor pada awalnya -

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

Formulir ToscaWidgets adalah turunan dari kelas tw2.forms.formkelas dasar. Widget yang diperlukan ditempatkan di dalam objek Layout. Dalam contoh ini,TableLayoutdigunakan. Widget ditampilkan dalam tabel dua kolom. Kolom pertama menunjukkan keterangan dan kolom kedua menunjukkan bidang input atau pilihan.

Objek TextField dibuat menggunakan konstruktor berikut -

twf.TextField(size, value = None)

Jika tidak disebutkan, objek BidangTeks mengambil ukuran default dan awalnya kosong. Saat mendeklarasikan objek TextArea, jumlah baris dan kolom dapat disebutkan.

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

Objek NumberField adalah TextField yang hanya dapat menerima angka. Panah atas dan bawah dibuat di perbatasan kanan untuk menambah atau mengurangi angka di dalamnya. Nilai awal juga dapat ditentukan sebagai argumen dalam konstruktor.

twf.NumberField(value)

Tepat di sebelah kanan kotak CalendarDatePicker, tombol kalender ditampilkan. Saat ditekan, pemilih tanggal akan muncul. Pengguna dapat mengetik tanggal secara manual di dalam kotak atau memilih dari pemilih tanggal.

twd.CalendarDatePicker()

Objek EmailField menyajikan TextField, tetapi teks di dalamnya harus dalam format email.

EmailID = twf.EmailField()

Formulir berikut juga memiliki RadioButtonList. Konstruktor kelas ini berisi objek List sebagai nilai parameter opsi. Tombol Radio untuk setiap opsi akan ditampilkan. Pilihan default ditentukan dengan parameter nilai.

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

CheckBoxList membuat kotak centang untuk setiap opsi dalam daftar.

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

Daftar dropdown disebut sebagai SingleSelectfield di perpustakaan ToscaWidgets ini. Item dalam objek Daftar yang sesuai dengan parameter opsi dari daftar drop-down. Teks terlihat disetel sebagai nilai parameter prompt_text.

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

Secara default, formulir menampilkan tombol Kirim dengan judul 'simpan'. Untuk menampilkan keterangan lain, buat objek SubmitButton dan tentukan sebagai parameter nilai.

twf.SubmitButton(value = 'Submit')

Formulir dikirimkan ke URL, yang ditentukan sebagai nilai parameter tindakan formulir. Secara default, data formulir dikirimkan dengan metode http POST.

action = 'URL'

Dalam kode berikut, formulir bernama AdmissionForm dirancang menggunakan widget yang dijelaskan di atas. Tambahkan kode ini di root.py sebelum kelas RootController.

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')

Sekarang simpan kode ini di bawah sebagai twform.html dalam direktori template -

<!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>

Di kelas RootController (di root.py), tambahkan fungsi controller berikut -

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

Di kelas AdmissionForm, kami punya stipulated/save_formsebagai URL tindakan. Oleh karena itu tambahkansave_form() berfungsi di RootController.

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

Pastikan server berjalan (menggunakan servis gearbox). Memasukkanhttp://localhost:8080/twform di browser.

Menekan tombol kirim akan mengirim data ini ke save_form() URL, yang akan menampilkan data form berupa objek kamus.

{
   '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'
}

Pustaka widget Formulir yang baik harus memiliki fitur validasi input. Misalnya, pengguna harus dipaksa memasukkan data di bidang wajib, atau memverifikasi apakah bidang email berisi email yang valid, tanpa menggunakan cara terprogram lainnya (seperti fungsi JavaScript) untuk validasi.

Versi awal ToscaWidgets Forms Library digunakan untuk mengandalkan modul FormEncode untuk dukungan validasi. ToscaWidgets2 sekarang memiliki dukungan validasi built-in yang tersedia dalam modul tw2.core. Namun, masih memungkinkan untuk menggunakan teknik validasi FormEncode.

Untuk memasukkan formulir ToscaWidgets ke validasi, @validate decorator digunakan.

@validate(form, error_handler, validators)
  • Itu ’form’ adalah objek formulir ToscaWidgets yang akan divalidasi.

  • Itu ‘error-handler’ adalah metode pengontrol yang digunakan untuk menangani kesalahan formulir.

  • Itu ‘validators’ adalah objek kamus yang berisi validator FormEncode.

Jenis Validator

Modul tw2.core berisi kelas validator yang mewarisi validator lain. Dimungkinkan juga untuk merancang validator khusus berdasarkan itu. Beberapa validator penting dijelaskan di bawah -

LengthValidator- Periksa apakah suatu nilai memiliki panjang yang ditentukan. Batas minimum dan maksimum ditentukan dengan parameter min dan max. Pesan khusus untuk panjang di bawah dan di atas min dan max dapat ditentukan sebagai parameter tooshort dan toolong.

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

RangeValidator- Biasanya digunakan bersama dengan RangeField. Ini berguna untuk memvalidasi nilai bidang numerik dalam batas minimum dan maksimum. Pesan untuk parameter tooshort dan toolong dapat disesuaikan.

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

IntValidator- Kelas ini diturunkan dari RangeValidator. Ini biasanya digunakan untuk memvalidasi jika input dalam bidang teks normal berisi data integer. Batas minimum dan maksimum serta pesan kesalahan dapat diatur. Selain itu, pesan kesalahan untuk input non-integer dapat ditentukan sebagai parameter 'notint'.

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

OneOfValidator - Validator ini memaksa pengguna untuk memilih nilai dari opsi yang tersedia di daftar saja.

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

DateValidator- Sangat berguna untuk memastikan bahwa input pengguna adalah tanggal yang valid. Format tanggal (default adalah YMD) dan pesan kesalahan dapat disesuaikan. Batas tanggal minimum dan maksimum juga dapat ditentukan. DateTimeValidator juga tersedia untuk memverifikasi objek kelas DateTime.

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

EmailValidator- Memvalidasi masukan pengguna terhadap alamat email yang valid. Kelas ini diwarisi dari RegexValidator yang lebih umum.

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

UrlValidator- Kelas ini juga diwarisi dari RegexValidator. Ini memvalidasi masukan pengguna untuk URL yang valid.

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

MatchValidator- Mengonfirmasi apakah nilai satu bidang cocok dengan yang lain. Ini sangat berguna, di mana pengguna diminta untuk memilih dan mengonfirmasi bidang kata sandi. Penggunaan umum MatchValidator ditunjukkan di bawah ini -

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()

Dimungkinkan juga untuk membangun validator gabungan, di mana validasi diinginkan untuk berhasil, jika salah satu pemeriksaan lolos. Dalam kasus lain, Anda mungkin ingin validasi berhasil, hanya jika input melewati semua pemeriksaan. Untuk ini, tw2.core menyediakan validator Any dan All, yang merupakan subclass dari CompoundValidator yang dapat diperpanjang.

TurboGears menyediakan sistem pesan yang sangat nyaman untuk memberi tahu informasi kepada pengguna dengan cara yang tidak mengganggu. Kelas TGFlash dalam modul tg menyediakan dukungan untuk pesan flashing yang disimpan dalam cookie biasa. Kelas ini mendukung pengambilan pesan flash di sisi server serta sisi klien melalui JavaScript.

Itu render()metode kelas TGFlash, ketika digunakan dari Python itu sendiri, dapat dipanggil dari template untuk membuat pesan flash. Jika digunakan pada JavaScript, ini menyediakan objek WebFlash. Itu mengekspospayload() dan render() metode untuk mengambil pesan flash saat ini dan merendernya dari JavaScript.

Saat proyek TurboGears dibuat menggunakan 'quickstart', ia memiliki template Master.html. Ini berisi definisi variabel dari objek flash itu. Isi pesan kilat ini yang diterima dari pengontrol menggantikan placeholder yang ditandai di templat ini.

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

Itu tg.flash_obj adalah objek WebFlash, yang tersedia di dalam template apa pun dengan menyertakan master.htmltemplate. Objek ini memungkinkan untuk mengambil pesan flash saat ini dan menampilkannya.

Pesan Flash disimpan dalam cookie (yang namanya secara default adalah webflash) dengan menggunakan tg.flash()metode. Parameter pesan dan status kemudian diteruskan ke sana.

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

Jika metode yang disebut flash melakukan pengalihan, maka flash akan terlihat di dalam halaman yang dialihkan. Jika metode ini secara langsung mengekspos template, maka flash akan terlihat di dalam template itu sendiri.

Penampilan pesan flash dapat disesuaikan dengan menerapkan gaya CSS ke kode status. Sebuah proyek 'quickstarted' berisi kesalahan, peringatan, info dan kode status ok yang disesuaikan dengan stylesheet public / css / style.css. Lebih banyak kode status dengan gaya juga dapat ditambahkan.

#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;
}

Style sheet eksternal ini perlu disertakan dalam template -

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

Konfigurasi dukungan pesan Flash apa pun dapat dicapai dengan mengatur parameter untuk metode configure () dari objek TGFlash atau di app_cfg.py (di folder config). Parameter yang dapat dikonfigurasi adalah -

Sr.No. Parameter & Deskripsi
1

flash.cookie_name

Nama cookie yang digunakan untuk menyimpan pesan flash. Default-nya adalahwebflash.

2

flash.default_status

Status pesan default jika tidak ditentukan (ok secara default)

3

flash.template

Digunakan sebagai flash template saat dirender.

4

flash.allow_html

Ternyata on/off escaping in flash messages, secara default HTML tidak diperbolehkan.

5

flash.js_call

Kode JavaScript yang akan dijalankan saat menampilkan flash dari JavaScript. Default-nya adalahwebflash.render()

6

flash.js_template

string.Template Misalnya digunakan untuk menggantikan dukungan JavaScript penuh untuk pesan flash.

  • pop_payload() - fungsi fetches current flash message, statusdan informasi terkait. Mendapatkan pesan flash akan menghapus cookie.

  • render(container_id, use_js=True) - Render pesan flash di dalam template atau berikan dukungan Javascript untuk mereka.

  • container_id adalah DIV tempat pesan akan ditampilkan, sementara use_js beralih antara merender flash sebagai HTML atau untuk penggunaan JavaScript.

  • status - Dapatkan hanya status flash saat ini, mendapatkan status flash akan menghapus cookie.

  • message - Dapatkan hanya pesan flash saat ini, menerima pesan flash akan menghapus cookie.

Bagaimana Cara Membuat Pesan Flash Sederhana?

Dalam contoh berikut, metode flash () disediakan di kelas pengontrol root. Ini memanggil pesan flash () yang diberikan ke template yang terbuka, flash.html

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 {}

Kode untuk membuat flash.html di folder template adalah sebagai berikut

<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>

Mulai server dan masuk http://localhost:8080/flash?user=MVL di browser

Ubah URL menjadi http://localhost:8080/flash dan melihat pesan flash diformat secara berbeda sesuai definisi di style.css

Seringkali diperlukan untuk menyimpan data penjelajahan sederhana yang dilampirkan ke browser pengguna. Sesi adalah teknik yang paling umum digunakan. Sesi mewakili data yang tidak perlu disimpan dalam bentuk yang lebih persisten seperti file disk atau database.

Namun, data sesi di TurboGears dapat didukung oleh sistem file, basis data, atau nilai cookie berciri. Sejumlah kecil data sesi umumnya disimpan dalam cookie, tetapi untuk volume data sesi yang lebih besar, MemCache digunakan.

MemCache adalah daemon tingkat sistem. Ini menyediakan akses cepat ke data cache dan sangat skalabel. Namun, ini dimaksudkan untuk digunakan hanya pada server yang aman, dan karenanya harus dijaga dan diamankan oleh sysadmin.

Beaker dalam Manajemen Sesi

TurboGears menggunakan Beaker untuk manajemen sesi. Proyek yang dimulai cepat oleh gearbox secara default dikonfigurasi untuk menggunakan cookie berciri untuk menyimpan data sesi.

Setiap kali klien terhubung, middleware sesi (Beaker) akan memeriksa cookie menggunakan nama cookie, yang telah ditentukan di file konfigurasi. Jika cookie tidak ditemukan, itu akan disetel di browser. Pada semua kunjungan berikutnya, middleware akan menemukan cookie dan memanfaatkannya.

Untuk mengaktifkan manajemen sesi, kelas sesi harus dimasukkan dalam proyek dengan mengikuti pernyataan import -

from tg import session

Untuk menyimpan data dalam variabel sesi -

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

Untuk mengambil variabel sesi -

return session[‘key’]

Perhatikan bahwa Anda perlu menyimpan sesi secara eksplisit agar kunci Anda disimpan dalam sesi itu.

Itu delete() metode objek sesi akan menghapus semua sesi pengguna -

session.delete()

Meskipun tidak biasa untuk menghapus semua sesi pengguna pada lingkungan produksi tertentu, Anda biasanya akan melakukannya untuk pembersihan setelah uji kegunaan atau fungsional selesai.

Diberikan di bawah ini adalah contoh sederhana untuk mendemonstrasikan sesi. Kelas RootController memilikisetsession() metode yang menetapkan variabel sesi.

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>"

Memasukkan http://localhost:8080/setsession

Tautan di browser mengarah ke http://localhost:8080/getsession yang mengambil dan menampilkan variabel sesi -

Untuk meningkatkan kinerja aplikasi web, terutama jika itu terlibat dalam operasi yang panjang, teknik cache digunakan. TurboGears menyediakan dua jenis teknik caching -

Whole-page Caching

Ia bekerja pada tingkat protokol HTTP untuk menghindari seluruh permintaan ke server dengan memiliki browser pengguna, atau server proxy perantara (seperti Squid) mencegat permintaan dan mengembalikan salinan file yang di-cache.

Application-level Caching

Ini berfungsi dalam server aplikasi untuk menyimpan nilai yang dihitung ke dalam cache, seringkali merupakan hasil dari kueri database yang kompleks, sehingga permintaan di masa mendatang dapat menghindari keharusan untuk menghitung ulang nilai. Untuk aplikasi web, cache tingkat aplikasi menyediakan cara yang fleksibel untuk menyimpan hasil dari kueri kompleks sehingga total beban dari metode pengontrol tertentu dapat dikurangi menjadi beberapa kueri khusus pengguna atau kasus tertentu dan overhead rendering template .

Caching tingkat aplikasi

Seperti yang disebutkan sebelumnya, proyek TurboGears 'quickstarted' dikonfigurasi untuk mengaktifkan paket Beaker untuk dukungan caching. Beaker mendukung ujung belakang berikut yang digunakan untuk penyimpanan cache -

  • memory- Digunakan untuk penyimpanan per proses. Ini sangat cepat.

  • filesystem - penyimpanan per proses serta multi-proses.

  • DBM database - per proses, multi proses, cukup cepat.

  • SQLAlchemy database- penyimpanan per-database-server. Lebih lambat dibandingkan dengan opsi yang diberikan di atas.

  • Memcached - cache berbasis memori multi-server.

Pengontrol Caching

Untuk cache pengontrol cepat, a cached()dekorator tersedia. Seluruh badan pengontrol di-cache tergantung pada berbagai parameter permintaan. Definisitg.decorators.cached() dekorator adalah sebagai berikut

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

Deskripsi parameter adalah sebagai berikut -

Sr.No. Parameter & Deskripsi
1

key

Menentukan parameter pengontrol yang digunakan untuk menghasilkan kunci cache.

2

expire

Waktu dalam detik sebelum cache kedaluwarsa, Default-nya adalah "tidak pernah".

3

Type

dbm, memory, file, memcached, atau None.

4

cache_headers

Tupel nama header yang menunjukkan header respons.

5

invalidate_on_startup

Jika Benar, cache tidak valid setiap kali aplikasi dimulai atau dimulai ulang.

6

cache_response

respon harus di-cache atau tidak, default ke True.

Berikut adalah contoh caching pengontrol -

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

Caching Level Template

Mesin template Genshi mengambil template dari cache jika isinya tidak berubah. Ukuran default cache ini adalah 25. Secara default, pemuatan ulang template otomatis adalah benar. Untuk meningkatkan kinerja, pengaturan berikut dapat dibuatapp_cfg.py -

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

Untuk menyimpan template, Anda hanya perlu mengembalikan file tg_cache opsi dari pengontrol yang membuat template yang di-cache.

Tg_cache adalah kamus yang menerima kunci berikut -

  • key - Kunci cache. Default: Tidak ada.

  • expire - berapa lama cache harus tetap hidup. Default: tidak pernah kedaluwarsa

  • type - memori, dbm, memcache. Default: dbm.

Contoh berikut menggambarkan cache template -

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

Meskipun dimungkinkan untuk menggunakan SQL dalam aplikasi TurboGears untuk melakukan operasi CRUD pada database relasional apa pun, disarankan untuk menggunakan SQLAlchemy, toolkit Python adalah Pemeta Relasi Objek yang kuat yang memberi pengembang aplikasi kekuatan penuh dan fleksibilitas SQL. Selain dukungan untuk database berbasis SQL melalui SQLAlchemy, TurboGears juga mendukung database MongoDB melalui Ming. Di bagian ini, fungsionalitas SQLAlchemy dibahas.

Apa itu ORM (Object Relational Mapping)?

Kebanyakan platform bahasa pemrograman berorientasi objek. Data di server RDBMS di sisi lain disimpan sebagai tabel. Pemetaan relasi objek adalah teknik memetakan parameter objek ke struktur tabel RDBMS yang mendasari. API ORM menyediakan metode untuk melakukan operasi CRUD tanpa harus menulis pernyataan SQL mentah.

Ketika proyek TurboGears dibuat menggunakan perintah 'quickstart' dari gearbox toolkit, dukungan SQLAlchemy diaktifkan secara default dengan pengaturan konfigurasi berikut -

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

Proyek 'quickstarted' juga membuat paket model di dalamnya. Misalnya, proyek 'Hello' akan memiliki model Hello \ hello \. File berikut dibuat dalam paket ini -

  • __init__.py- Di sinilah akses database disiapkan. Objek model aplikasi diimpor dalam modul ini. Ia juga memiliki DBSession - manajer sesi global dan juga DeclarativeBase, yang merupakan kelas dasar untuk semua kelas model.

  • auth.py- Di sinilah model yang digunakan oleh tumpukan otentikasi ditentukan. Model database tambahan disimpan dalam paket ini, sebagai modul terpisah, dan ditambahkan di __init__.py.

Mari kita tambahkan model siswa yang akan menyiapkan tabel siswa di sqlite database.

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 = '')

Sekarang tambahkan model ini init_model() berfungsi di dalam __init__.py.Fungsi ini sudah memuat model autentikasi di dalamnya. Tambahkan model siswa kita di bawahnya.

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

Jika Anda ingin tabel diinisialisasi dengan beberapa data pada saat menyiapkan model, tambahkan di bootstrap.py dalam paket websetup. Tambahkan pernyataan berikut dibootstrap() fungsi.

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()

Model diinisialisasi dengan menjalankan perintah aplikasi pengaturan gearbox -

gearbox setup-app

Objek sesi dari SQLAlchemy mengelola semua operasi ketekunan objek ORM.

Metode sesi berikut melakukan Operasi CRUD -

  • DBSession.add(model object) - menyisipkan catatan ke dalam tabel yang dipetakan.

  • DBSession.delete(model object) - menghapus catatan dari tabel.

  • DBSession.query(model).all() - mengambil semua record dari tabel (sesuai dengan query SELECT).

Anda dapat menerapkan filter ke kumpulan record yang diambil dengan menggunakan atribut filter. Misalnya, untuk mengambil record dengan city = 'Hyderabad' dalam tabel siswa, gunakan pernyataan berikut -

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

Sekarang kita akan melihat bagaimana berinteraksi dengan model melalui URL pengontrol.

Pertama mari kita rancang formulir ToscaWidgets untuk memasukkan data siswa

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')

Di RootController (root.py dari aplikasi Hello), tambahkan pemetaan fungsi berikut '/ tambahkan' 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)

Simpan kode HTML berikut sebagai studentform.html di folder template -

<!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>

Memasukkan http://localhost:8080/adddi browser setelah memulai server. Formulir informasi siswa berikut akan terbuka di browser -

Formulir di atas dirancang untuk diserahkan ke ‘/save_record’URL. Oleh karena itu asave_record() fungsi perlu ditambahkan di root.pyuntuk mengeksposnya. Data dari bentuk siswa diterima oleh fungsi ini sebagai adict()obyek. Ini digunakan untuk menambahkan record baru dalam tabel siswa yang mendasari model siswa.

@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")

Harap dicatat bahwa setelah penambahan berhasil, browser akan dialihkan ke ‘/listrec’ URL. URL ini diekspos oleh alistrec() function. Fungsi ini memilih semua record dalam tabel siswa dan mengirimkannya dalam bentuk objek dict ke template studentlist.html. Inilistrec() fungsinya adalah sebagai berikut -

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

Template studentlist.html melakukan iterasi melalui objek kamus entri menggunakan py: untuk direktif. Template studentlist.html adalah sebagai berikut -

<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>

Sekarang kunjungi kembali http://localhost:8080/adddan memasukkan data ke dalam formulir. Dengan mengklik tombol kirim, browser akan dibawa ke studentlist.html. Ini juga akan mem-flash pesan 'catatan baru berhasil ditambahkan'.

ToscaWidgets berisi kontrol DataGrid yang menyediakan cara cepat untuk menyajikan data dalam bentuk tabel. Objek Datagrid dideklarasikan sebagai berikut -

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

Sekarang, fungsi showgrid () mengambil semua record dalam tabel siswa dan mengekspos data ke template grid.html. Pertama kode untuk fungsi showgrid () dan kemudian kode grid.html diberikan di bawah ini -

showgrid ()

@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>

Data tabel berikut akan ditampilkan kapan http://localhost:8080/showlist URL dimasukkan di browser -

TurboGears menyediakan dekorator praktis yang disebut paginate () untuk membagi keluaran di halaman. Dekorator ini dikombinasikan dengan dekorator expose (). Dekorator @Paginate () mengambil objek kamus dari hasil kueri sebagai argumen. Selain itu, jumlah record per halaman ditentukan oleh nilai atribut items_per_page. Pastikan Anda mengimpor fungsi paginate dari tg.decorators ke dalam kode Anda.

Tulis ulang fungsi listrec () di root.py sebagai berikut -

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)

Item per halaman disetel menjadi tiga.

Di template studentlist.html, navigasi halaman diaktifkan dengan menambahkan tmpl_context.paginators.entries.pager () di bawah direktif py: for. Kode untuk template ini harus seperti di bawah ini -

<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>

Memasukkan http://localhost:8080/listrecdi browser. Halaman pertama rekaman dalam tabel akan ditampilkan. Di atas tabel ini, tautan ke nomor halaman juga terlihat.

Cara Menambahkan Dukungan Penomoran Halaman ke Datagrid

Anda juga dapat menambahkan dukungan pagination ke datagrid. Dalam contoh berikut, datagrid berpaginasi dirancang untuk menampilkan tombol tindakan. Untuk mengaktifkan objek datagrid tombol aksi dibangun dengan kode berikut -

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)))) ])

Di sini tombol tindakan ditautkan ke parameter nama setiap baris di kisi data.

Tulis ulang showgrid() berfungsi sebagai berikut -

@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)

Browser menunjukkan datagrid paginasi sebagai berikut -

Dengan mengklik tombol Edit di baris ketiga, ini akan dialihkan ke URL berikut http://localhost:8080/edit?name=Rajesh+Patil

TurboGears menyediakan ekstensi tgext.admin, yang didukung oleh tgext.crud dan sprox. Sprox ini adalah paket yang digunakan untuk pembuatan widget web langsung dari skema database. Ini dapat digunakan untuk membuat halaman administrasi sederhana secara otomatis dan merupakan toolkit yang menjalankan halaman / admin dalam aplikasi yang baru dimulai secara cepat.

Secara default, admin akan memberikan akses yang dibuat secara otomatis ke semua model yang diimpor dalam model proyek Anda / __ init__.py.

Cara Membuat Admin TurboGears

Admin TurboGears default dibuat sebagai objek kelas AdminController -

from tgext.admin.controller import AdminController

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

Ini membuat admin untuk semua model dengan konfigurasi admin TurboGears default.

Melalui manajer, pengguna telah dibuat selama fase penyiapan. Sekarang, Anda dapat memperoleh akses ke Admin TurboGears dihttp://localhost:8080/adminPertama kali halaman ini diakses, ia akan meminta otentikasi. Anda cukup memberikan nama pengguna dan kata sandi pengguna yang dibuat oleh perintah aplikasi pengaturan untuk kami -

Username: manager
Password: managepass

Untuk masuk ke proyek quickstart, tambahkan fungsi berikut ke kelas RootController (controllers / 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)

Masuk ke aplikasi 'quickstarted' setelah memulai server dan dengan mengunjungi http://localhost:8080/loginlalu masukkan kredensial manajer seperti yang ditampilkan di atas. Browser akan menampilkan halaman admin seperti yang ditunjukkan di bawah ini -

Halaman tersebut menunjukkan semua model yang dibuat dalam aplikasi ini. Anda dapat mengklik model apa pun untuk melihat daftar entri di dalamnya -

Tombol 'Baru' di atas datagrid ini memungkinkan catatan ditambahkan. Demikian pula, tombol tindakan untuk mengedit dan menghapus record juga tersedia di kolom tindakan pada datagrid ini. Kotak pencarian juga ditampilkan untuk memilih rekaman secara bersyarat.

Aplikasi TurboGears dibuat dengan opsi quickstart dan setup-app dari gearbox toolkit, yang memiliki otorisasi dan dukungan otentikasi diaktifkan secara default. Model yang dideklarasikan dalam auth.py diatur dan diinisialisasi sesuai nilai yang ditetapkan dalam bootstrap.py.

Model berikut dideklarasikan di auth.py -

Model Pengguna

Model User berisi desain tabel tg_user. Tabel ini digunakan oleh paket repose.who. Paket repose.who ini adalah pustaka otentikasi yang andal dan dapat diperluas untuk aplikasi WSGI. Struktur model pengguna adalah sebagai berikut -

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)

Model grup ini berisi definisi tabel tg_group. Definisinya diberikan di auth.py sebagai berikut -

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)

Izin model lain juga disiapkan, yang berisi definisi izin.

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))

Pada saat menyiapkan model, data berikut ditambahkan dalam tabel ini -

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)

Model Predikat

Modul predikat dalam paket tg berisi definisi untuk pemeriksa predikat. Predikat adalah syarat yang harus dipenuhi agar pengguna dapat mengakses sumber yang diminta. Predikat atau kondisi seperti itu dapat terdiri dari lebih banyak predikat - itu disebut predikat majemuk. Pengontrol tindakan, atau pengontrol, mungkin hanya memiliki satu predikat, baik itu tunggal atau gabungan.

Jika pengguna tidak masuk, atau tidak memiliki izin yang tepat, pemeriksa predikat ini melempar 401 (HTTP Unauthorized), yang ditangkap oleh middleware repoze.who untuk menampilkan halaman login yang memungkinkan pengguna untuk login, dan mengarahkan pengguna kembali ke halaman yang benar setelah selesai.

Kondisi atau predikat berbeda yang ditentukan dalam modul tg.predicates adalah -

Sr.No. modul tg.predicates & Deskripsi
1

All

Periksa apakah semua predikat yang ditentukan terpenuhi

2

Any

Periksa apakah setidaknya satu dari predikat tertentu terpenuhi

3

is_user

Periksa apakah nama pengguna yang diautentikasi adalah yang ditentukan

4

in_group

Periksa apakah pengguna termasuk dalam grup tertentu.

5

in_all_groups

Periksa apakah pengguna termasuk dalam semua grup yang ditentukan.

6

in_any_group

Periksa apakah pengguna termasuk dalam setidaknya salah satu grup yang ditentukan.

7

is_anonymous

Periksa apakah pengguna saat ini anonim.

8

has_permission

Periksa apakah pengguna saat ini memiliki izin yang ditentukan.

9

has_all_permissions

Periksa apakah pengguna saat ini telah diberikan semua izin yang ditentukan.

10

has_any_permission

Periksa apakah pengguna memiliki setidaknya satu dari izin yang ditentukan.

Misalnya, jika Anda memiliki predikat yaitu grant access user belonging to customers group, maka Anda dapat menggunakan pemeriksa predikat bawaan berikut -

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

Pemeriksa predikat berikut akan memberikan akses ke pengguna 'root' atau siapa pun dengan izin 'kelola' -

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 juga mendukung database dokumen MongoDB. Ini menggunakan Ming, API Pemeta Dokumen Objek. Penggunaan Ming sangat mirip dengan SQLAlchemy. Bahasa kueri Ming memungkinkan port proyek TurboGears berbasis SQLAlchemy ke Ming.

Apa itu PyMongo

PyMongo adalah distribusi Python yang berisi alat untuk bekerja dengan MongoDB. Ming memperluas PyMongo menyediakan -

  • Model Deklaratif
  • Validasi dan Konversi Skema
  • Evolusi Skema
  • Implementasi InMemory MongoDB Murni
  • Unit Kerja
  • Peta Identitas
  • Hubungan Satu-ke-Banyak, Banyak-ke-Satu dan Banyak-ke-Banyak

Pertama-tama, Anda perlu mengunduh dan menginstal MongoDB. Distribusi MongoDB terbaru dapat diunduh darihttps://www.mongodb.org/downloads

Di Windows, mulai server MongoDB dengan menyediakan opsi -dbpath -

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

D:\mongo folderditujukan untuk menyimpan database MongoDB. Server mulai mendengarkan padahttp://localhost:27017. Sekarang untuk memulai shell MongoDB gunakan perintah berikut -

C:\mongodb\bin>Mongo

Lingkungan MongoDB kita sekarang sudah siap.

Sekarang buat proyek TurboGears dengan opsi -ming -

gearbox quickstart --ming Hello

Proyek yang dimulai dengan cepat ini akan menyediakan lapisan otentikasi dan otorisasi seperti yang disediakan untuk versi SQLAlchemy. Aplikasi ini sekarang akan mencoba menyambung ke server pada port 27017 di mesin lokal. File development.ini dalam folder proyek berisi pengaturan berikut -

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

Siapkan proyek menggunakan perintah berikut -

Python setup.py develop

Folder proyek berisi subfolder model yang memiliki file berikut -

  • __init__.py - Di sinilah databaseakses sudah diatur. Koleksi Anda seharusnyaimported into this module. Misalnya, kami akan menambahkan koleksi siswa dalam paket ini.

  • session.py - File ini mendefinisikan session of your database connection. Anda perlu mengimpor ini setiap kali Anda harus mendeklarasikan fileMappedClass untuk menentukan sesi perform queries.

  • auth.py - File ini akan dibuat, jika Anda punya enabled authentication and authorizationdi panduan memulai. Ini mendefinisikan tiga koleksirepoze.who, yang selanjutnya bergantung pada: Pengguna, Grup, dan Izin.

Mendefinisikan Koleksi Anda

Secara default, TurboGears mengkonfigurasi Ming dalam mode deklaratif. Ini mirip dengan dukungan deklaratif SQLAlchemy dan membutuhkan setiap model untuk mewarisi dari kelas MappedClass.

MappedClass mensyaratkan subkelas __mongometa__ tersedia di dalamnya, yang selanjutnya memberikan detail tentang nama koleksi yang menyimpan dokumen dan sesi yang digunakan untuk menyimpan dokumen.

MappedClass juga berisi definisi bidang dalam dokumen. Modul odm Ming memiliki definisi berbagai jenis properti bidang -

  • FieldProperty
  • ForeignIdProperty
  • RelationProperty

Itu ming.schema module mendefinisikan tipe data berikut -

  • 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

Untuk menambahkan koleksi siswa dalam model ini, simpan kode berikut sebagai student.py di folder hello / models.

Halo \ models \ student.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 = ''))

Terakhir, sertakan model ini di hello \ models \ __ init__.py

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

Untuk menyiapkan model ini, jalankan perintah gearbox berikut -

Gearbox setup-app

Mulai server dengan perintah gearbox berikut -

Gearbox serve –reload –debug

Buka beranda aplikasi ini (http://localhost:8080/)dan masuk dengan kredensial manajer. Halaman admin aplikasi ini akan menampilkan daftar model yang disiapkan. (login sebagai pengelola, pengelolaan sandi)

Pembuatan koleksi juga dapat diverifikasi di antarmuka web MongoDB serta shell MongoDB.

Sesi ODMS digunakan untuk melakukan beberapa operasi database menggunakan fungsi berikut -

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

Mendesain Formulir ToscoWidget

Sekarang kita akan mendesain formulir ToscoWidget untuk memasukkan data siswa dan menambahkannya ke dalam tabel yang mendasari model siswa.

Berikut adalah kode untuk membuat studentform.py -

Halo \ 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')

Dalam aplikasi Rootcontroller '/ add' URL yang memanggil fungsi add (), yang akan membuka formulir yang dirancang di atas di browser. Tombol kirimnya kemudian memanggil fungsi save_record (). Itu mengambil data formulir dan menyimpannya dalam tabel siswa dan mengarahkan aplikasi ke URL '/ listrec', yang memperlihatkan templat daftar siswa.

Root.py untuk aktivitas ini adalah sebagai berikut -

Halo / controllers / 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")

Template berikut dibuat di folder template -

Halo \ 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>

Halo \ 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>

Mulai ulang server dan masuk http://localhost:8080/add di browser -

Setiap kali data ditambahkan dan tombol kirim ditekan, daftar entri saat ini akan ditampilkan.

Gearbox toolkit berisi perintah scaffold, yang sangat berguna untuk membuat komponen baru aplikasi TurboGears dengan cepat. Aplikasi yang dihasilkan oleh perintah quickstart dari gearbox memiliki kerangka kerangka di folder model (model.py.template), folder templat (templat.html.template) dan folder pengontrol (controller.py.template). File '.template' ini digunakan sebagai dasar untuk membuat perancah baru untuk aplikasi

Misalnya, untuk membuat model baru bernama mymodel, cukup jalankan perintah berikut -

gearbox scaffold model mymodel

Perintah ini akan menghasilkan model / mymodel.py dengan kelas model baru yang ditentukan di dalamnya.

# -*- 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']

Pengguna sekarang dapat membuat modifikasi dalam struktur tabel sesuai kebutuhan mereka dan kemudian mengimpornya ke dalam model/__init__.py untuk membuat model tersedia di dalam aplikasi.

Untuk membuat model, kelas pengontrol untuk menanganinya dan halaman indeks, ketiga komponen ini dapat dibuat secara bersamaan dengan perintah berikut.

gearbox scaffold model controller template mymodel

Perintah ini akan menghasilkan controllers \ mymodel.py di mana kelas MymodelController didefinisikan dengan semestinya.

# -*- 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')

Untuk mulai menggunakan pengontrol ini, pasang di dalam aplikasi Anda RootController hanya untuk mendefinisikan sebuah instance dari MymodelController. Tambahkan baris-baris ini di dalam controllers \ root.py -

From hello.controller.mymodel import MymodelController

class RootController(BaseController): mymodel = MymodelController()

Template scaffold templates \ mymodel.html juga akan dibuat di folder templates. Ini akan bertindak sebagai halaman indeks untuk URL '/ mymodel'.

Yang dihasilkan mymodel.html file di folder template akan menjadi sebagai berikut -

<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>

Ada tiga cara di TurboGears untuk menyambungkan perilaku di dalam aplikasi yang sudah ada.

  • Hook - Ini adalah mekanisme yang memungkinkan untuk mendefinisikan suatu peristiwa, dan memberi tahu pendengar terdaftar saat dan kapan peristiwa itu dipancarkan.

  • Controller Wrapper- Itu berada di antara TurboGears dan Controller, sehingga dimungkinkan untuk memperluas controller seperti dekorator. Dengan demikian, ini dapat dilampirkan ke aplikasi pengontrol pihak ketiga mana pun.

  • Application Wrapper - Ini mirip dengan middleware WSGI, tetapi hanya bekerja dalam konteks TurboGears.

Di sini, di bab ini, kita akan membahas cara menggunakan hook di dalam aplikasi yang sudah ada.

Pengait

Hooks adalah peristiwa yang terdaftar di file konfigurasi aplikasi app_cfg.py. Setiap pengontrol kemudian dihubungkan ke acara ini oleh dekorator acara.

Pengait berikut ditentukan di TurboGears -

Sr.No. Hooks & Description
1

Startup()

application wide only, dipanggil saat aplikasi dimulai.

2

shutdown()

aplikasi hanya lebar, dipanggil saat aplikasi keluar.

3

configure_new_app

aplikasi baru dibuat oleh konfigurator aplikasi.

4

before_config(app)

aplikasi hanya luas, dipanggil tepat setelah membuat aplikasi, tetapi sebelum mengatur opsi dan middleware

5

after_config(app)

aplikasi hanya lebar, dipanggil setelah menyelesaikan pengaturan semuanya.

6

before_validate

Dipanggil sebelum melakukan validasi

7

before_call

Dipanggil setelah validasi, sebelum memanggil metode pengontrol yang sebenarnya.

8

before_render

Dipanggil sebelum merender template pengontrol, keluarannya adalah nilai kembali pengontrol.

9

after_render

Dipanggil setelah selesai merender template pengontrol.

Daftarkan Hook

Untuk register a Hook, buat fungsi di app_cfg.py dan kemudian daftarkan mereka menggunakan kode berikut -

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

Dalam kode berikut, pengait on_startup, on_shutdown dan before_render terdaftar di app_cfg.py.

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)

Hook before_render terdaftar dengan fungsi pengontrol di Rootcontroller. Tambahkan kode berikut di controllers \ root.py.

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')

Saat aplikasi disajikan, pesan start up ditampilkan di konsol.

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

Saat URL '/' dimasukkan di browser, pesan yang sesuai dengan hook before_render ditampilkan di konsol.

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

Ekstensi TurboGears diidentifikasi oleh tgext.* package. Toolkit Gearbox menyediakan perintah tgext untuk membuat ekstensi sampel. Misalnya -

gearbox tgext -n myextension

Parameter opsional lainnya untuk perintah ini adalah -

  • --author - nama pembuat paket.

  • --email - email penulis paket.

  • --licence- lisensi yang digunakan untuk paket. Default-nya adalah MIT.

  • --description - Deskripsi paket.

  • --keywords - Kata kunci paket (default: turbogears2.extension).

Ini akan membuat direktori tgext.myextension, yang memiliki ekstensi contoh sederhana di dalamnya.

Run the setup.py di dalam direktori -

Python setup.py install

Itu _init_.py file di dalam tgext/myextension folder berisi -

  • Plugme function - Ini adalah titik masuk perpanjangan.

  • SetupExtension class - inisialisasi ekstensi terjadi di sini.

  • On_startup function - di dalam kelas ada hook yang terdaftar pada fungsi __call__ di dalam kelas.

Versi singkat dari 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!')

Setelah ekstensi dipasang, hidupkan dengan membuat tambahan berikut di aplikasi app_cfg.py file konfigurasi.

from tgext.myextension import plugme

plugme(base_config)

Jika kami meluncurkan server menggunakan perintah server gearbox, pemberitahuan tentang ekstensi yang baru terdaftar dapat dilihat di konsol dengan berikut -

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

Jika ekstensi Anda perlu mengekspos model dan pengontrol, Anda mungkin ingin melihat Pluggable Applications, yang dimaksudkan untuk membuat aplikasi Turbogears yang dapat digunakan kembali yang dapat dipasang di dalam aplikasi lain untuk memperluas fitur mereka.

Gunakan perintah gearbox berikut untuk membuat aplikasi yang dapat dicolokkan -

gearbox quickstart-pluggable plugtest

Aplikasi yang dapat dicolok ini dapat menentukannya sendiri -

  • Controllers - yang akan dipasang secara otomatis, saat aplikasi dihapus.

  • Models - yang akan tersedia di dalam dan di luar aplikasi yang terpasang.

  • Helpers - yang dapat secara otomatis diekspos di objek 'H' dalam template aplikasi.

  • Bootstrap - yang akan dieksekusi ketika aplikasi-pengaturan dipanggil.

  • Statics - yang akan tersedia di jalur pribadinya sendiri.

Instal aplikasi plugtest ini dan pasang yang sama dengan melakukan modifikasi berikut di app_cfg.py.

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

REST adalah singkatan dari REpresentasi State Transfer. REST adalah arsitektur berbasis standar web dan menggunakan Protokol HTTP untuk komunikasi data. Ini berputar di sekitar sumber daya di mana setiap komponen adalah sumber daya dan sumber daya diakses oleh antarmuka umum menggunakan metode standar HTTP. REST pertama kali diperkenalkan olehRoy Fielding in 2000.

Apa itu RestController

RestController di TurboGears menyediakan mekanisme untuk mengakses metode permintaan, bukan hanya URL. Kalimat standar HTTP meliputi: GET, POST, PUT, dan DELETE. RestController mendukung ini, dan juga menambahkan beberapa pintasan untuk pengiriman URL yang membuat menampilkan data sebagai formulir dan daftar, sedikit lebih mudah bagi pengguna.

Untuk menjelaskan bagaimana RESTful bekerja dengan TurboGears, kami akan mendefinisikan layanan web sederhana yang menampilkan daftar siswa.

Kode untuk model siswa diberikan di bawah ini -

model \ student.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 = '')

Sekarang buat pengontrol berdasarkan RestController dan berikan fungsi tampilan untuk membuat daftar siswa dalam format json.

Controllers \ 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)

Pasang StudentController ini di aplikasi RootController dengan memasukkan baris berikut di root.py -

from hello.controllers.student import StudentController

class RootController(BaseController):

   students = StudentController()

Pergi ke http://localhost:8080/students itu akan memberikan daftar siswa kami yang dikodekan dalam format json.

Kami menggunakan metode posting untuk menentukan bagaimana kami menyimpan siswa kami ke database. Metode ini dipanggil setiap kali http://localhost:8080/student url diakses menggunakan permintaan POST -

@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)

Menggunakan get_one() metode, kita dapat menampilkan satu item dari database ke pengguna -

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

PUT adalah metode yang digunakan untuk memperbarui catatan yang ada menggunakan REST -

@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)

Kuda kerja penghapusan dilampirkan ke metode post_delete. Di sini kami benar-benar menghapus catatan dari database, dan kemudian mengarahkan kembali ke halaman daftar -

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

Untuk beralih dari lingkungan pengembangan ke lingkungan produksi yang lengkap, aplikasi perlu diterapkan di server web nyata. Bergantung pada apa yang Anda miliki, ada berbagai opsi yang tersedia untuk menerapkan aplikasi web TurboGears.

Apache dengan mod_wsgi

Mod_wsgi adalah modul Apache yang dikembangkan oleh Graham Dumpleton. Ini memungkinkan program WSGI dilayani menggunakan server web Apache.

Pertama, instal Apache 2.X untuk platform Anda, jika belum selesai. Setelah Anda menginstal Apache, instal mod_wsgi. Buat dan aktifkan lingkungan virtual Python di server dan instal TurboGears di dalamnya.

Instal aplikasi Anda dalam application director, lalu buat skrip bernama app.wsgi.

Konfigurasi instalasi Apache sebagai berikut -

<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>

Mulai ulang Apache

Tipe http://www.site1.com/ di browser untuk mengakses aplikasi.

TurboGears di bawah Circus dan Chaussette

Sirkus adalah manajer proses & soket. Ini dapat digunakan untuk memantau dan mengontrol proses dan soket. Saat dipasangkan dengan server WSGI Chaussette, ini bisa menjadi alat yang ampuh untuk menyebarkan aplikasi Anda dan mengelola proses terkait yang dibutuhkan aplikasi Anda.

TurboGears - GoogleAppEngine

Instal SDK Google AppEngine untuk Python dari URL berikut - https://cloud.google.coms

Instal Google AppEngine di sistem Anda. Kemudian buka konsol Pengembang Google dan masuk dengan Akun Google Anda -https://console.developers.google.com/start

Buat proyek baru bernama mytgapp -

Menggunakan Peluncur Google AppEngine, buat aplikasi baru bernama mytgapp.

File-file berikut akan dibuat di direktori yang ditentukan -

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

Secara default, aplikasi yang dibuat bergantung pada kerangka Webapp2. Untuk menghapus ketergantungan ini, edit file app.yaml dan hapus bagian berikut -

libraries:
   - name: webapp2
   version: "2.5.2"

Buat lingkungan virtual sementara di direktori bernama mytgapp dan instal TurboGears. Buat aplikasi TurboGears di dalamnya. Sekarang kita dapat melanjutkan mengedit filemain.py file yang dijalankan oleh AppEngine untuk menjalankan aplikasi kita dan benar-benar menulis aplikasi TurboGears di sana.

Tambahkan konten berikut di 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()

Sekarang jalankan aplikasi dari AppEngine Launcher dan klik tombol browse untuk melihat bahwa aplikasi berfungsi dengan baik di localhost.

Kami telah membuat proyek bernama mytgapp di konsol pengembang. Sekarang klik tombol terapkan di Launcher. Setelah proses penerapan selesai,http://mytgapp.appspot.com/ kunjungi untuk melihat aplikasi kami secara online.