Turbogears-quick-guide

提供:Dev Guides
移動先:案内検索

TurboGears-概要

Web Frameworkとは何ですか?

Web Application Frameworkまたは単にWeb Frameworkは、ライブラリやモジュールのコレクションを表します。これにより、Webアプリケーション開発者は、プロトコル、スレッド管理などの低レベルの詳細を気にすることなく、アプリケーションを作成できます。

Webフレームワーク

TurboGearsとは何ですか?

TurboGearsは、Pythonで書かれたWebアプリケーションフレームワークです。 2005年にKevin Dangoorによって作成された最新バージョンのTurboGears(ver 2.3.7)は、Mark RammとFlorent Aideが率いる開発者グループによって管理されています。

TurboGearsは、Models-View-Controllerパラダイムに従い、Rails、Django、Strutsなどの最新のWebフレームワークのほとんどと同じです。

モデルビューコントローラ

MVCは、Webアプリケーションを開発するためのソフトウェア設計パターンです。 Model View Controllerパターンは3つの部分で構成されています-

  • モデル-パターンの最低レベルは、データの維持を担当します。
  • 表示-データのすべてまたは一部をユーザーに表示します。
  • Controller -モデルとビュー間の相互作用を制御するソフトウェアコード。

MVCは、アプリケーションロジックをユーザーインターフェイスレイヤーから分離し、懸念の分離をサポートするため、人気があります。 ここで、コントローラーはアプリケーションに対するすべてのリクエストを受信し、モデルと連携してビューに必要なデータを準備します。 ビューは、コントローラーによって準備されたデータを使用して、最終的な提示可能な応答を生成します。 MVCの抽象化は、次のようにグラフィカルに表すことができます-

MVC

モデル

モデルは、アプリケーションのデータの管理を担当します。 ビューからの要求に応答し、コントローラーからの指示にも応答して、それ自体を更新します。

景色

コントローラーがデータを表示する決定をトリガーとして、特定の形式でデータを表示します。 スクリプトベースのテンプレートシステムであり、AJAXテクノロジーとの統合が非常に簡単です。

コントローラー

コントローラーは、ユーザー入力に応答し、データモデルオブジェクトで相互作用を実行します。 コントローラーは入力を受け取り、入力を検証してから、データモデルの状態を変更するビジネスオペレーションを実行します。

TurboGearsは、多数のライブラリとツールの上に構築されています。 これらのツールは、TurboGearsの異なるバージョン間で変更されています。 現在のバージョン(ver 2.3.7)のコンポーネントは以下のとおりです。

SQLAlchemy

Pythonコードのオブジェクトリレーションマッピング(ORM)を提供するオープンソースのSQLキットです。

SQLAlchemy

げんし

このテンプレートエンジンは、TGアプリケーションのフロントエンドを構築するために使用されます。 Webテンプレートシステムは、テンプレートを特定のデータソースと組み合わせて、動的なWebページをレンダリングします。

ToscaWidgets

サーバー側のコントロールを使用してHTMLフォームを生成するためのウィジェットライブラリです。 Toscaは、JavaScriptウィジェットおよびツールキットと接続するためのミドルウェアとしても機能します。

ギアボックス

プロジェクトとサーバーTurboGearsアプリケーションを管理するためのコマンドセットを提供します。 TurboGearsアプリケーションは、WSGI準拠のWebサーバーに展開できます。

Web Server Gateway Interface(WSGI)は、Python Webアプリケーション開発の標準として採用されています。 WSGIは、WebサーバーとWebアプリケーション間のユニバーサルインターフェイスの仕様です。 wsgirefパッケージは、WSGIの参照実装です。 Web TurboGears WebフレームワークにWSGIサポートを追加するために使用されます。 このパッケージのsimple_serverモジュールは、WSGIアプリケーションを提供する単純なHTTPサーバーを実装します。 このチュートリアルで開発したアプリケーションをテストするために使用します。

TurboGears-環境

前提条件

Python 2.6以降。 TurboGearsの以前のバージョンは、Python 3.Xに準拠していませんでした。 最新バージョンは、Python 3.Xでうまく機能すると主張しています。 ただし、TurboGearsの公式ドキュメントはまだPython 2.7環境に基づいています。

次のコマンドは、 virtualenv をインストールします-

pip install virtualenv

このコマンドには administrator 特権が必要です。 Linux/Mac OSでpip の前に sudoを追加します。 Windowsを使用している場合は、管理者としてログインします。 Ubuntuでは、パッケージマネージャーを使用してvirtualenvをインストールできます。

Sudo apt-get install virtualenv

インストールすると、新しい仮想環境がフォルダーに作成されます。

mkdir newproj
cd newproj
virtualenv venv

対応する環境をアクティブにするには、 Linux/OS X

venv/bin/activate
*Windows* で
venv\scripts\activate

この環境にTurboGearsをインストールする準備ができました。 TurboGearsの最小限のインストールは、次のコマンドによって行われます-

pip install TurboGears2

上記のコマンドは、システム全体のインストールの仮想環境なしで直接実行できます。

TurboGearsを開発ツールと一緒にインストールするには、次のコマンドを使用します-

pip install tg.devtools

TurboGears-最初のプログラム

TurboGearsには、単一ファイルアプリケーションをすばやく作成できる最小モードがあります。 最小限の依存関係セットで簡単な例とサービスを迅速に構築できます。

TGアプリケーションのアプリケーションクラスは、 TGController クラスから継承されます。 このクラスのメソッドは、 tg モジュールから @ expose デコレーターによってアクセスできます。 最初のアプリケーションでは、* index()メソッドがアプリケーションのルートとしてマップされます。 TGControllerクラスも *tg モジュールからインポートする必要があります。

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

次に、アプリケーションの構成を設定し、アプリケーションオブジェクトを宣言します。 ここでの AppConfig クラスコンストラクターは、trueに設定された最小属性とコントローラークラスの2つのパラメーターを取ります。

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

ここの* make_wsgi_app()*関数は、アプリケーションオブジェクトを構築します。

このアプリケーションを提供するには、HTTPサーバーを起動する必要があります。 前述のように、 wsgiref パッケージの simple_server モジュールを使用してセットアップし、起動します。 このモジュールには、引数としてポート番号とアプリケーションオブジェクトを必要とする* make_server()*メソッドがあります。

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

これは、アプリケーションがローカルホストのポート番号8080で提供されることを意味します。

以下は、最初のTurboGearsアプリケーションの完全なコードです-

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

Pythonシェルから上記のスクリプトを実行します。

Python app.py

ブラウザのアドレスバーに http://localhost:8080 と入力して、「Hello World TurboGears」メッセージを表示します。

TurboGearsの tg.devtools にはGearboxが含まれています。 これは、より複雑なTGプロジェクトの管理に役立つ一連のコマンドです。 次のGearboxコマンドを使用して、フルスタックプロジェクトをすばやく作成できます-

gearbox quickstart HelloWorld

これにより、 HelloWorld というプロジェクトが作成されます。

TurboGears-依存関係

TurboGearsプロジェクトには、次のディレクトリが含まれています-

  • Config -プロジェクトのセットアップと構成が依存する場所
  • コントローラー-すべてのプロジェクトコントローラー、Webアプリケーションのロジック
  • i018n -サポートされている言語の翻訳ファイル
  • Lib -ユーティリティPython関数とクラス
  • モデル-データベースモデル
  • 公開静的ファイル-CSS、JavaScript、画像
  • テンプレート-コントローラーによって公開されるテンプレート。
  • テスト-完了したテストのセット。
  • Websetup -アプリケーションのセットアップ時に実行する機能。

プロジェクトをインストールする方法

このプロジェクトをインストールする必要があります。 setup.py はプロジェクトのベースディレクトリに既に提供されています。 このスクリプトが実行されると、プロジェクトの依存関係がインストールされます。

Python setup.py develop

デフォルトでは、プロジェクトのセットアップ時に次の依存関係がインストールされます-

  • ビーカー
  • げんし
  • zope.sqlalchemy
  • sqlalchemy
  • アレンビック
  • repoze.who
  • tw2.forms
  • tgext.admin≥0.6.1
  • WebHelpers2
  • バベル

インストール後、シェルで次のコマンドを発行して、開発サーバーでプロジェクトの提供を開始します-

Gearbox serve –reload –debug

上記のコマンドに従って、ビルド済みのサンプルプロジェクトを提供します。 ブラウザで http://localhost:8080 を開きます。 この既製のサンプルアプリケーションは、TurboGearsフレームワーク自体について簡単に紹介しています。

プロジェクトウィンドウ

このHelloプロジェクトでは、デフォルトのコントローラーがコントローラーディレクトリに Hello/hello/controllers.root.py として作成されます。 次のコードで root.py を変更しましょう-

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"

基本的な作業アプリケーションの準備ができたら、コントローラークラスにビューを追加できます。 上記の Mycontroller クラスには、新しいメソッド* sayHello()が追加されています。 * @ expose()*デコレータは、それに */sayHello URLを添付します。 この関数は、URLからパラメーターとして名前を受け入れるように設計されています。

「ギアボックスサービス」コマンドでサーバーを起動した後、 http://localhost:8080 。 Hello Worldメッセージは、次のURLが入力されてもブラウザに表示されます-

*http://localhost:8080/*
*http://localhost:8080/index*

これらすべてのURLは* RootController.index()メソッドにマッピングされます。 このクラスには、URLが特定の関数にマッピングされていない場合に呼び出される _default()*メソッドもあります。 URLへの応答は、@ expose()デコレーターによって関数にマップされます。

URLから公開された関数にパラメーターを送信することができます。 次の関数は、URLから名前パラメーターを読み取ります。

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

次の出力は、URLに対する応答としてブラウザに表示されます- http://localhost:8080/?name = MVL

Hello MVL

TurboGearsは、URLパラメーターを関数の引数に自動的にマップします。 RootControllerクラスはBaseControllerから継承されます。 これは、アプリケーションの* libフォルダー*で base.py として定義されます。

そのコードは次のとおりです-

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 __* は、リクエストがルーティングされるControllerメソッドにディスパッチします。

TurboGears-配信テンプレート

HTMLコンテンツはブラウザに返されますが、より高度な出力を得るには、テンプレートエンジンの使用が常に推奨されます。 ギアボックスによって「クイックスタート」されるフルスタックプロジェクトでは、Genshiがデフォルトのテンプレートレンダラーとして有効になっています。 ただし、最小限のアプリケーションでは、Genshi(またはjinjaなどの他のテンプレートエンジン)をインストールして有効にする必要があります。 Genshiテンプレートエンジンは、純粋なxhtmlでテンプレートを記述し、コンパイル時に問題を検出して破損したページの提供を防ぐためにテンプレートを検証することを許可します。

テンプレートは、ドット表記を使用して参照されます。 Helloプロジェクトでは、テンプレートWebページを保存するためのテンプレートディレクトリが提供されています。 したがって、 samplelhello.templates.sample (拡張子は言及されていません)として参照されます。 TurboGearsは、* tg.render_template()*関数によってコントローラーメソッドをリンクするための公開デコレーターを介してこのテンプレートをレンダリングします。

公開されたコントローラー関数は、Python辞書オブジェクトを返します。 このディクショナリオブジェクトは、リンクされたテンプレートに順番に渡されます。 テンプレートのプレースホルダーには、辞書の値が入力されます。

まず、プレーンHTMLスクリプトを使用してWebページを表示します。 HTMLスクリプト内で解析するデータを送信するつもりはないため、公開されたコントローラーは* null辞書オブジェクト*を返します。

サンプルHTMLを作成する方法

*samplel* を以下に示します。 プロジェクトのテンプレートディレクトリに保存されていることを確認してください。
<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>

   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
   </body>
</html>
*root.py* に* sample()*関数を追加し、それを介してsamplelを公開します。
@expose("hello.templates.sample")
   def sample(self):
      return {}

Webサーバーの起動後にURL http://localhost:8080/sample を入力すると、次の結果がブラウザーに表示されます。

結果の表示

上記のように、辞書オブジェクトはパラメーターのコレクションとしてGenshiテンプレートに送信されます。 このテンプレートには、コントローラーから受信したパラメーターが動的に入力される「プレースホルダー」が含まれています。

  • sample()*関数を変更して、辞書オブジェクトをサンプルテンプレートに送信します。
@expose("hello.templates.sample")
   def sample(self,name):
      mydata = {'person':name}
      return mydata

テンプレートフォルダーに samplel を作成します( templates \ samplel

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>

   <body>
      <h2>Hello, my name is ${person}!.</h2>
   </body>
</html>

上記のHTMLコードでは、 $ \ {person} がプレースホルダーです。 ブラウザでURLとして http://localhost:8080/sample?name = MVL を入力します。 このURLは、ルートコントローラーの* sample()*メソッドにマッピングされます。 辞書オブジェクトを返します。 これは、templatesディレクトリのリンクされたテンプレートページsamplelによって選択されます。 その後、Webページで$ \ {person}がMVLに置き換えられます。

コントローラ関数でHTMLフォームデータにアクセスすることもできます。 HTMLフォームはフォームデータの送信に使用します。

結果

TurboGears-HTTPメソッド

Httpプロトコルは、World Wide Webのデータ通信の基盤です。 このプロトコルでは、指定されたURLからデータを取得するさまざまな方法が定義されています。 次の表は、さまざまなhttpメソッドをまとめています-

Sr.No. HTTP Methods & Description
1

GET

暗号化されていない形式でデータをサーバーに送信します。 最も一般的な方法。

2

HEAD

GETと同じですが、応答本文はありません

3

POST

HTMLフォームデータをサーバーに送信するために使用されます。 POSTメソッドによって受信されたデータは、サーバーによってキャッシュされません。

4

PUT

ターゲットリソースの現在のすべての表現を、アップロードされたコンテンツで置き換えます。

5

DELETE

URLで指定されたターゲットリソースの現在の表現をすべて削除します

HTMLフォームの作成

HTMLフォームを作成し、フォームデータをURLに送信します。 次のスクリプトをloginlとして保存します

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

このフォームに入力されたデータは、 '/login' URL に送信されます。 次に、コントローラー関数* loginpage()*を作成し、上記のHTMLページを公開します。

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

フォームデータを受信するには、パラメーターとしてフォーム属性を持つ* login()*コントローラーを提供します。 ここで、「nm」はログインフォームのテキスト入力フィールドの名前で、login()関数のパラメーターとして使用されます。

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

ご覧のように、ログインフォームから受信したデータは、サンプルテンプレート(以前に使用)に送信されています。 次の出力を生成するために* Genshiテンプレートエンジン*によって解析されます-

げんし結果

POSTメソッド

HTMLフォームがPOSTメソッドを使用してアクション属性のURLにデータをディスパッチする場合、フォームデータはURLで公開されません。 エンコードされたデータは、コントローラー関数によって dict 引数で受信されます。 以下の** kw 引数は、データを保持する辞書オブジェクトです。

HTMLフォームには2つの入力テキストフィールドが含まれます。

<html>
   <body>

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

   </body>
</html>
  • marks()コントローラーはフォームデータを受け取り、それを *samplel テンプレートに送信します。 root.py のコードは次のとおりです-
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

最後に、samplelテンプレートは次のとおりです-

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

サーバーを起動します(まだ実行されていない場合)

Gearbox server –reload –debug
ブラウザに *http://localhost
8080/marksform* と入力します

サンプルテンプレート

*samplel* は次の出力をレンダリングします-

サンプルHTML結果

TurboGears-Genshiテンプレート言語

Genshiは、XMLベースのテンプレート言語です。 TurboKearsの以前のバージョンのテンプレートエンジンであった Kid に似ています。 GenshiとKidは、 HSLT、TALPHP などの他の有名なテンプレート言語に触発されています。

Genshiテンプレートは、処理ディレクティブで構成されています。 これらのディレクティブは、テンプレート内の要素と属性です。 Genshiディレクティブは、ネームスペースhttp://genshi.edgewall.org/で定義されています。 したがって、この名前空間はテンプレートのルート要素で宣言する必要があります。

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

上記の宣言は、デフォルトのネームスペースがXHTMLに設定され、Genshiディレクティブに「py」プレフィックスが付いていることを意味します。

げんし指令

Genshiでは多くのディレクティブが定義されています。 以下のリストはGenshiディレクティブを列挙します-

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

条件付きセクション

Genshiは、コンテンツの条件付きレンダリングのための2つのディレクティブpy:ifおよびpy:chooseを提供します。

py:if

このディレクティブの要素のコンテンツは、* if句*の式がtrueと評価された場合にのみレンダリングされます。 テンプレートコンテキストのデータが \ {'foo':True、 'bar': 'Hello'} であると仮定すると、次のディレクティブ-

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

になります

Hello

ただし、 'foo’がFalse に設定されている場合、この出力はレンダリングされません。

このディレクティブは要素としても使用できます。 この場合、 <py:if> は対応する </py:if> で閉じる必要があります

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

py:choose

*py:choose* を *py:when* および *py:otherwise* ディレクティブと組み合わせて使用​​すると、高度な条件付き処理が可能です。 この機能は、 *C/C ++* の *switch – case* コンストラクトに似ています。
*py:choose* ディレクティブの式は、 *py:when* 代替で識別される異なる値でチェックされ、対応するコンテンツがレンダリングされます。 デフォルトの代替は、 *py:otherwise* ディレクティブの形式で提供できます。
<div py:choose = "foo”>
   <span py:when = "0">0</span>
   <span py:when = "1">1</span>
   <span py:otherwise = "">2</span>
</div>

次の例は、 py:choose および py:when ディレクティブの使用法を示しています。 HTMLフォームは/marks URLにデータを投稿します。 * marks()関数はマークをリダイレクトし、辞書オブジェクトの形式で結果を *totall テンプレートにリダイレクトします。 result Pass/Fail の条件付き表示は、 py:choose および py:when ディレクティブを使用して実現されます。

マークを入力するHTMLスクリプト( marksl )は次のとおりです-

<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>
*root.py* の完全なコードは次のとおりです。 * marks()*コントローラはマークと結果を *totall* テンプレートに送信しています-
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

テンプレートフォルダーの totall は辞書データを受け取り、次のように条件付きでhtml出力に解析します-

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

サーバーを起動します(まだ実行されていない場合)

Gearbox server –reload –debug
ブラウザに *http://localhost
8080/marksform* と入力します-

結果ウィンドウ

  • 合計*は次の出力をレンダリングします-

Total Html

py:for

py:forディレクティブの要素は、反復可能な(通常はPython Listオブジェクト)の各アイテムに対して繰り返されます。 items = [1,2,3] がテンプレートコンテキストに存在する場合、次のpy:forディレクティブによって反復できます-

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

次の出力がレンダリングされます-

1
2
3

次の例は、py:forディレクティブを使用してtotallテンプレートでレンダリングされたHTMLフォームデータを次のように使用できることを示しています-

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

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>
  • loop()*コントローラーはフォームデータを読み取り、リストオブジェクトの形式でtotal.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.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})

templテンプレートはpy:forループを使用して、dictオブジェクトのコンテンツをテーブルの形式でレンダリングします。

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

サーバーを起動します(まだ実行されていない場合)

gearbox server –reload –debug
ブラウザに *http://localhost
8080/marksform* と入力します。

ウィンドウ結果

上記のフォームが送信されると、次の出力がブラウザーに表示されます。

フォーム出力

py:def

このディレクティブは、マクロを作成するために使用されます。 マクロは、テンプレートコードの再利用可能なスニペットです。 Python関数と同様に、名前があり、オプションでパラメーターを指定できます。 このマクロの出力は、テンプレートの任意の場所に挿入できます。

py:defディレクティブは次の構文に従います-

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

このマクロは、「name」パラメーターの変数値でレンダリングできます。

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

このディレクティブは、次のような構文の別のバージョンでも使用できます-

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

次の例では、 root.py の* macro()コントローラーが、name1とname2の2つのキーを持つ *dict オブジェクトをmacrolテンプレートに送信します。

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

このマクロテンプレートには、グリーティングと呼ばれるマクロの定義が含まれています。 コントローラから受信したデータのグリーティングメッセージを生成するために使用されます。

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

ギアボックスを使用してサーバーを起動します

gearbox serve –reload –debug

ブラウザに次のURLを入力して、macro()コントローラーを呼び出します-

*http://localhost:8080/macro*

次の出力はブラウザでレンダリングされます-

定義例

py:with

このディレクティブを使用すると、ローカル変数に式を割り当てることができます。 これらのローカル変数により、内部の表現がより冗長で効率的になります。

テンプレートのコンテキストデータでx = 50が与えられていると仮定すると、py:withディレクティブは次のようになります-

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

それは次の出力になります-

50 50 100

py:withディレクティブの代替バージョンも利用可能です-

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

次の例では、macro()コントローラーは、名前、phy、および数学キーを持つdictオブジェクトを返します。

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}

テンプレートmacrolは、py:withディレクティブを使用して、phyおよびmathsキーの値を追加します。

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

ブラウザは、URL http://localhost:8080/macro に応じて次の出力をレンダリングします

Py:for Example

構造操作ディレクティブ

*py:attrs* ディレクティブは、要素の属性を追加、変更、または削除します。
<ul>
   <li py:attrs = "foo">Bar</li>
</ul>
*foo = \ {'class': ’collapse'}* がテンプレートコンテキストに存在する場合、上記のスニペットがレンダリングします。
<ul>
   <li class = "collapse">Bar</li>
</ul>
*py:content* ディレクティブは、ネストされたコンテンツを式の評価結果に置き換えます-
<ul>
   <li py:content = "bar">Hello</li>
</ul>

コンテキストデータにbar = 'Bye’とすると、これは

<ul>
   <li>Bye</li>
</ul>
*py:replace* ディレクティブは、要素自体を式の評価結果に置き換えます-
<div>
   <span py:replace = "bar">Hello</span>
</div>

コンテキストデータにbar = 'Bye’と指定すると、生成されます

<div>
   Bye
</div>

TurboGears-含まれています

別のXMLドキュメント(特にHTMLドキュメント)のコンテンツを含めるには、現在のドキュメントに包含タグを使用します。 このような包含を有効にするには、HTMLドキュメントのルート要素でXInclude名前空間を宣言する必要があります。

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

上記の宣言では、includeディレクティブに ’xi’ プレフィックスが含まれることを指定しています。 現在のドキュメントに別のHTMLページのコンテンツを追加するには、次のようにxi:includeディレクティブを使用します-

<xi:include href = "somepagel"/>

次の例では、root.pyにinclude()コントローラーが含まれており、includelを公開しています。

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

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

見出しとフッターHTML

includelでは、include名前空間が宣言され、headinglおよびfooterlの内容が追加されます。 これがtemplates \ includelの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 = "headingl"/>
      <h2>main content </h2>
      <xi:include href = "footerl"/>
   </body>

</html>

これがtemplates \ headinglコードです-

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>

   <body>
      <h1>This is page Header</h1>
   </body>
</html>

以下はtemplates \ footerlです

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>

   <body>
      <h3>This is page footer</h3>
   </body>
</html>

ギアボックスを使用して開発を開始し、ブラウザーに http://localhost:8080/include と入力します。 レンダリングされた出力は以下のようになります-

テンプレートの例

このようにして、ビューのモジュール構造を実現できます。 xi:includeディレクティブに記載されているリソースが利用できない場合、エラーが発生します。 このような場合、xi:fallbackを使用して代替リソースをロードできます。

<xi:include href = “mainl”>
   <xi:fallback href = ”defaultl”/>
</xi.include>

コンテンツを含めることは、式を含むことができるhref属性として動的にすることができます。

root.pyに次のコントローラーを追加します。

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

次のコードをref-includelとしてテンプレートフォルダーに保存します。

<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}l" py:for = "name in pages"/>
   </body>

</html>

サーバーを起動する前に、テンプレートフォルダに見出し、メイン、フッターがあることを確認してください。 ブラウザに http://localhost:8082/refinclude と入力して、次の出力を取得します

フッターテンプレート

TurboGears-JSONレンダリング

  • @ expose()デコレータは、デフォルトでhtmlコンテンツをレンダリングします。 ただし、これは *json content type に設定できます。 TurboGearsは、 tg.jsonify.JSONEncoder(_ * kwargs _)*クラスによるjsonレンダリングをサポートしています。 JSONデータをレンダリングするには、デコレータを公開するためにコンテンツタイプとしてjsonを渡すだけです。
@expose('json')
def jsondata(self, **kwargs):
   return dict(hello = 'World')

「/jsondata」URLがブラウザに入力された場合、それは表示することによって応答します-

{"hello": "World"}

jsonpレンダリング

jsonpは、パディング付きのjsonを表します。 コントローラから返されたすべての値を関数の引数として提供するjavascript関数への呼び出しでアプリケーション/javascript応答を提供するという事実を除いて、json出力と同様に機能します。

jsonpレンダリングを有効にするには、まずアプリケーション内で必要なエンジンのリストに config/app_cfg.py を追加する必要があります-

base_config.renderers.append('jsonp')

次のように公開デコレータを記述します-

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

/jsonpdata?callback = callmeにアクセスすると、次のように表示されます-

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

TurboGears-URL階層

Webアプリケーションでは、複数のレベルを持つURL構造が必要になる場合があります。 TurboGearsは、オブジェクト階層をトラバースして、要求を処理できる適切なメソッドを見つけることができます。

ギアボックスを使用した「クイックスタート」プロジェクトには、プロジェクトのlibフォルダーにBaseControllerクラスがあります。 「Hello/hello/lib/base.py」として利用できます。 すべてのサブコントローラーの基本クラスとして機能します。 アプリケーションにサブレベルのURLを追加するには、BaseControllerから派生したBlogControllerというサブクラスを設計します。

このBlogControllerには、index()とpost()の2つのコントローラー関数があります。 どちらもテンプレート、ブログ、投稿を公開するように設計されています。

-これらのテンプレートはサブフォルダ内に配置されます-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}

次のようにRootControllerクラス(root.py内)でこのクラスのオブジェクトを宣言します-

class RootController(BaseController):
   blog = BlogController()

トップクラスURLの他のコントローラー関数は、以前と同様にこのクラスにあります。

URL http://localhost:8080/blog/ を入力すると、BlogControllerクラス内のindex()コントローラー関数にマップされます。 同様に、 http://localhost:8080/blog/post はpost()関数を呼び出します。

ブログと投稿のコードは以下の通りです-

Blogl

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

postl

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

URL http://localhost:8080/blog/ を入力すると、次の出力が生成されます-

ブログ

URL http://localhost:8080/blog/post を入力すると、次の出力が生成されます-

ブログ投稿

TurboGears – ToscaWidgetsフォーム

Webアプリケーションの最も重要な側面の1つは、ユーザーにユーザーインターフェイスを提示することです。 HTMLは、インターフェースの設計に使用される<form>タグを提供します。 テキスト入力、ラジオ、選択などのフォームの要素 適切に使用できます。 ユーザーが入力したデータは、GETまたはPOSTメソッドのいずれかにより、サーバー側スクリプトにHttp要求メッセージの形式で送信されます。

サーバー側のスクリプトは、http要求データからフォーム要素を再作成する必要があります。 そのため、この効果では、フォーム要素を2回定義する必要があります(HTMLで1回、サーバー側スクリプトで1回)。

HTMLフォームを使用する別の欠点は、フォーム要素を動的にレンダリングすることが(不可能ではないにしても)難しいことです。 HTML自体は、ユーザーの入力を検証する方法を提供しません。

ToscaWidgets2

TurboGearsは、柔軟なフォームレンダリングおよび検証ライブラリであるToscaWidgets2に依存しています。 ToscaWidgetsを使用して、Pythonスクリプトでフォームフィールドを定義し、HTMLテンプレートを使用してそれらをレンダリングできます。 tw2フィールドに検証を適用することもできます。

ToscaWidgetsライブラリは、多くのモジュールのコレクションです。 いくつかの重要なモジュールは以下のとおりです-

  • tw2.core -コア機能を提供します。 このモジュールのウィジェットは、エンドユーザーが利用できるようには意図されていません。
  • tw2.forms -これは基本的なフォームライブラリです。 フィールド、フィールドセット、フォーム用のウィジェットが含まれています。
  • tw2.dynforms -これには動的フォーム機能が含まれます。
  • tw2.sqla -これはSQLAlchemyデータベースのインターフェースです。

tw2.forms

これには、カスタムフォームのベースとして機能するFormクラスが含まれています。 2列テーブルのフィールドのレンダリングに役立つTableFormクラスがあります。 ListFormは、フィールドを順不同リストで表示します。

次の表は、tw2.formsモジュールで最も一般的に使用されるフィールドのタイプを示しています-

Sr.No. Fields & Description
1

TextField

単一行のテキスト入力フィールド

2

TextArea

複数行のテキスト入力フィールド

3

CheckBox

ラベル付きのチェック可能な長方形のボックスを提示します

4

CheckBoxList

複数選択可能なグループpfチェックボックス

5

RadioButton

選択/選択解除するトグルボタン

6

RadioButtonList

相互に排他的なラジオボタンのグループ

7

PasswordField

テキストフィールドに似ていますが、入力キーは表示されません

8

CalendarDatePicker

ユーザーが日付を選択できるようにします

9

SubmitButton

フォームを送信するボタン

10

ImageButton

画像が上部にあるクリック可能なボタン

11

SingleSelectField

リストから単一の項目を選択できるようにします

12

MultipleSelectField

リストから複数のアイテムを選択できるようにします

13

FileField

ファイルをアップロードするためのフィールド

14

EmailField

メール入力フィールド

15

URLField

URLを入力する入力フィールド

16

NumberField

番号スピンボックス

17

RangeField

数値スライダー

次の例では、これらのウィジェットの一部を使用したフォームが構築されます。 これらのウィジェットのほとんどはtw2.formsで定義されていますが、CalendarDateFieldはtw2.Dynformsモジュールで定義されています。 したがって、tw2.coreと一緒にこれらのモジュールの両方が最初にインポートされます-

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

ToscaWidgetsフォームは、 tw2.forms.form 基本クラスから派生したクラスです。 必要なウィジェットは、レイアウトオブジェクト内に配置されます。 この例では、 TableLayout が使用されます。 ウィジェットは2列のテーブルに表示されます。 最初の列はキャプションを示し、2番目の列は入力または選択フィールドを示します。

TextFieldオブジェクトは、次のコンストラクタを使用して作成されます-

twf.TextField(size, value = None)

言及されていない場合、TextFieldオブジェクトはデフォルトのサイズを取り、最初は空白です。 TextAreaオブジェクトの宣言中に、行と列の数が言及される場合があります。

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

NumberFieldオブジェクトは、数字のみを受け入れることができるTextFieldです。 上下の矢印が右の境界線に生成され、その内側の数が増減します。 初期値は、コンストラクターの引数として指定することもできます。

twf.NumberField(value)

CalendarDatePickerボックスのすぐ右側に、カレンダーボタンが表示されます。 押すと、日付セレクターがポップアップします。 ユーザーは、ボックスに日付を手動で入力するか、日付セレクターから選択できます。

twd.CalendarDatePicker()

EmailFieldオブジェクトはTextFieldを提示しますが、その中のテキストは電子メール形式でなければなりません。

EmailID = twf.EmailField()

次のフォームにもRadioButtonListがあります。 このクラスのコンストラクターには、optionsパラメーターの値としてListオブジェクトが含まれます。 各オプションのラジオボタンが表示されます。 デフォルトの選択は、valueパラメーターで指定されます。

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

CheckBoxListは、リスト内の各オプションのチェックボックスをレンダリングします。

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

ドロップダウンリストは、このToscaWidgetsライブラリでSingleSelectfieldとして呼び出されます。 オプションパラメータに対応するListオブジェクトのアイテムは、ドロップダウンリストを形成します。 表示されるキャプションは、prompt_textパラメーターの値として設定されます。

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

デフォルトでは、フォームにはキャプションが「保存」の「送信」ボタンが表示されます。 別のキャプションを表示するには、SubmitButtonオブジェクトを作成し、値パラメーターとして指定します。

twf.SubmitButton(value = 'Submit')

フォームはURLに送信されます。URLは、フォームのアクションパラメーターの値として指定されます。 デフォルトでは、フォームデータはhttp POSTメソッドによって送信されます。

action = 'URL'

次のコードでは、AdmissionFormという名前のフォームが上記のウィジェットを使用して設計されています。 このコードをRootControllerクラスの前のroot.pyに追加します。

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

次に、このコードを twforml としてテンプレートディレクトリに保存します-

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

   <head>
      <title>TurboGears Form Example</title>
   </head>

   <body>
      <div id = "tw form">
         ${form.display(value = dict(title = 'default title'))}
      </div>
   </body>

</html>

RootControllerクラス(root.py内)で、次のコントローラー関数を追加します-

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

AdmissionFormクラスには、アクションURLとして stipulated/save_form があります。 したがって、RootControllerに* save_form()*関数を追加します。

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

サーバーが実行されていることを確認します(ギアボックスサービスを使用)。 ブラウザに http://localhost:8080/twform と入力します。

フォーム

[送信]ボタンを押すと、このデータが* save_form()* URLに投稿され、辞書データの形式でフォームデータが表示されます。

{
   'EmailID': u'lathkar@yahoo.com',
   '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'
}

TurboGears –検証

優れたフォームウィジェットライブラリには、入力検証機能が必要です。 たとえば、ユーザーは、検証のために他のプログラム手段(JavaScript関数など)に頼ることなく、必須フィールドにデータを入力するか、電子メールフィールドに有効な電子メールが含まれているかどうかを確認する必要があります。

ToscaWidgets Forms Libraryの初期バージョンは、検証サポートのためにFormEncodeモジュールに依存していました。 ToscaWidgets2には、tw2.coreモジュールで利用可能なビルトイン検証サポートがあります。 ただし、FormEncode検証手法を使用することは引き続き可能です。

ToscaWidgetsフォームを検証するために、@ validateデコレーターが使用されます。

@validate(form, error_handler, validators)
  • 'form' は、検証するToscaWidgetsフォームオブジェクトです。
  • 'error-handler' は、フォームエラーの処理に使用されるコントローラーメソッドです。
  • 'validators' は、FormEncodeバリデーターを含む辞書オブジェクトです。

バリデーターの種類

tw2.coreモジュールには、他のバリデーターが継承されるバリデータークラスが含まれています。 また、それに基づいてカスタムバリデーターを設計することもできます。 重要なバリデータのいくつかを以下に説明します-

*LengthValidator* -値に規定の長さがあるかどうかを確認します。 最小および最大制限は、minおよびmaxパラメーターで定義されます。 minshortおよびmaxongパラメータの長さの上下にあるカスタムメッセージを指定できます。
tw2.core.LengthValidator(min = minval, max = maxval,
   msgs = { 'tooshort': (‘message for short length’),
   'toolong': (‘message for long length)})
*RangeValidator* -通常、RangeFieldとともに使用されます。 最小および最大制限内の数値フィールドの値を検証すると便利です。 tooshortおよびtoolongパラメーターのメッセージはカスタマイズできます。
tw2.core.RangeValidator(min = minval, max = maxval,
   msgs = { 'tooshort': (‘message for short length’),
   'toolong': (‘message for long length)})
*IntValidator* -このクラスはRangeValidatorから派生しています。 これは通常、通常のテキストフィールドへの入力に整数データが​​含まれているかどうかを検証するために使用されます。 最小制限と最大制限、およびエラーメッセージを設定できます。 さらに、非整数入力のエラーメッセージは「notint」パラメーターとして指定できます。
tw2.core.IntValidator(msgs = {‘notint’:’Must be Integer’})
*OneOfValidator* -このバリデーターは、リスト内の利用可能なオプションからのみ値を選択するようユーザーに強制します。
tw2.core.OneOfValidator(values = [option1, option2,..],
   msgs = {‘notinlist’:’Not in List’}}
*DateValidator* -ユーザー入力が有効な日付であることを確認するのに非常に便利です。 日付形式(デフォルトはY-M-D)およびエラーメッセージはカスタマイズ可能です。 最小および最大の日付制限も指定できます。 DateTimeValidatorは、DateTimeクラスのオブジェクトを検証するためにも使用できます。
tw2.core.DateValidator(msgs = {format = ’%Y-%m-%d’,
   'baddatetime': ('baddate', ('Must follow date format $format_str'))}
*EmailValidator* -有効なメールアドレスに対してユーザー入力を検証します。 このクラスは、より一般的なRegexValidatorから継承されます。
tw2.core.EmailValidator(msgs = {'badregex': ('bademail',
   ('Must be a valid email address')) }
*UrlValidator* -このクラスはRegexValidatorからも継承されます。 有効なURLのユーザー入力を検証します。
tw2.core.UrlValidator(msgs = {'badregex': ('badurl', ('Must be a valid URL’)) }
*MatchValidator* -1つのフィールドの値が他のフィールドと一致するかどうかを確認します。 これは、ユーザーがパスワードフィールドを選択して確認する必要がある場合に特に便利です。 MatchValidatorの一般的な使用法を以下に示します-
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()

いずれかのチェックに合格した場合、検証が成功することが望まれる複合バリデーターを構築することもできます。 その他の場合、入力がすべてのチェックに合格した場合にのみ、検証を成功させることができます。 このため、tw2.coreはAnyおよびAllバリデーターを提供します。これらは、拡張可能なCompoundValidatorのサブクラスです。

TurboGears –フラッシュメッセージ

TurboGearsは、目立たない方法でユーザーに情報を通知するための非常に便利なメッセージングシステムを提供します。 tgモジュールのTGFlashクラスは、プレーンCookieに保存されているメッセージのフラッシュをサポートします。 このクラスは、JavaScriptを介したクライアント側だけでなくサーバー側でのフラッシュメッセージの取得をサポートします。

TGFlashクラスの* render()メソッドをPython自体から使用する場合、テンプレートから呼び出してフラッシュメッセージをレンダリングできます。 JavaScriptで使用する場合、WebFlashオブジェクトを提供します。 * payload()*および render()*メソッドを公開して、現在のフラッシュメッセージを取得し、JavaScriptからレンダリングします。

「クイックスタート」を使用してTurboGearsプロジェクトを作成すると、Masterlテンプレートが作成されます。 そのFlashオブジェクトの変数の定義が含まれています。 コントローラから受信したこのフラッシュメッセージの内容は、このテンプレート内のマークされたプレースホルダーを置き換えます。

<py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
   <div py:if = "flash" py:replace = "Markup(flash)"/>
</py:with>
*tg.flash_obj* はWebFlashオブジェクトで、レンダリングされたテンプレート内で *masterl* テンプレートを含めることで利用できます。 このオブジェクトを使用すると、現在のフラッシュメッセージを取得して表示できます。

Flashメッセージは、* tg.flash()*メソッドを使用して、Cookie(デフォルトではwebflash)に保存されます。 その後、メッセージとステータスパラメータがそれに渡されます。

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

フラッシュと呼ばれるメソッドがリダイレクトを実行する場合、リダイレクトされたページ内にフラッシュが表示されます。 メソッドがテンプレートを直接公開する場合、フラッシュはテンプレート自体の内部に表示されます。

ステータスコードにCSSスタイルを適用することにより、フラッシュメッセージの外観をカスタマイズできます。 「クイックスタート」プロジェクトには、スタイルシートpublic/css/style.cssによってカスタマイズされたエラー、警告、情報、およびOKステータスコードが含まれます。 スタイル付きのステータスコードを追加することもできます。

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

この外部スタイルシートは、テンプレートに含める必要があります-

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

Flashメッセージサポートの構成は、TGFlashオブジェクトのconfigure()メソッドのパラメーターを設定するか、app_cfg.py(configフォルダー内)でパラメーターを設定することで実現できます。 設定可能なパラメータは次のとおりです-

Sr.No. Parameters & Description
1

flash.cookie_name

フラッシュメッセージの保存に使用されるCookieの名前。 デフォルトは webflash です。

2

flash.default_status

指定しない場合のデフォルトのメッセージステータス(デフォルトでOK)

3

flash.template

レンダリング時に* flashテンプレート*として使用されます。

4

flash.allow_html

  • Flashメッセージでのエスケープのオン/オフを切り替えます。デフォルトではHTMLは許可されていません。
5
  • flash.js_call*

JavaScriptからフラッシュを表示するときに実行されるJavaScriptコード。 デフォルトは* webflash.render()*です

6

flash.js_template

  • string.Template* インスタンスは、フラッシュメッセージのJavaScriptサポートを完全に置き換えるために使用されます。
  • * pop_payload()-関数*現在のフラッシュメッセージ、ステータス、および関連情報を取得します。 フラッシュメッセージを取得すると、Cookieが削除されます。
  • * render(container_id、use_js = True)*-テンプレート内のフラッシュメッセージをレンダリングするか、Javascriptサポートを提供します。
  • container_id はメッセージが表示されるDIVであり、use_jsはフラッシュをHTMLとしてレンダリングするかJavaScriptを使用するかを切り替えます。
  • status -現在のフラッシュステータスのみを取得し、フラッシュステータスを取得するとCookieが削除されます。
  • メッセージ-現在のフラッシュメッセージのみを取得し、フラッシュメッセージを取得するとCookieが削除されます。

シンプルなFlashメッセージを作成する方法は?

次の例では、ルートコントローラークラスでflash()メソッドが提供されています。 公開されたテンプレートflashlにレンダリングされるflash()メッセージを呼び出します

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

テンプレートフォルダーに flashl を作成するためのコードは次のとおりです。

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

サーバーを起動し、ブラウザーに http://localhost:8080/flash?user = MVL と入力します

フラッシュメッセージ

URLを http://localhost:8080/flash に変更し、style.cssの定義に従って異なる形式のフラッシュメッセージを確認します。

メッセージ

TurboGears –クッキーとセッション

多くの場合、ユーザーのブラウザに添付された簡単な閲覧データを保持する必要があります。 セッションは、最も一般的に使用される手法です。 セッションは、ディスクファイルやデータベースなどのより永続的な形式で保存する必要のないデータを表します。

ただし、TurboGearsのセッションデータは、ファイルシステム、データベース、またはハッシュされたCookieの値によってバックアップできます。 通常、少量のセッションデータがCookieに保持されますが、セッションデータの量が多い場合はMemCacheが使用されます。

MemCacheはシステムレベルのデーモンです。 キャッシュされたデータへの高速アクセスを提供し、非常にスケーラブルです。 ただし、セキュリティで保護されたサーバーでのみ使用することを目的としているため、sysadminによって保守および保護する必要があります。

セッション管理のビーカー

TurboGearsは、セッション管理にBeakerを使用します。 ギアボックスによってクイックスタートされるプロジェクトは、デフォルトでハッシュされたCookieを使用してセッションデータを保存するように構成されています。

クライアントが接続するたびに、セッションミドルウェア(ビーカー)は、構成ファイルで定義されているCookie名を使用してCookieを検査します。 Cookieが見つからない場合、ブラウザで設定されます。 その後のすべてのアクセスで、ミドルウェアはCookieを見つけて使用します。

セッション管理を有効にするには、次のインポートステートメントによってセッションクラスをプロジェクトに組み込む必要があります-

from tg import session

セッション変数にデータを保存するには-

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

セッション変数を取得するには-

return session[‘key’]

キーをセッションに保存するには、セッションを明示的に保存する必要があることに注意してください。

セッションオブジェクトの* delete()*メソッドは、すべてのユーザーセッションを消去します-

session.delete()

特定の運用環境ですべてのユーザーセッションを削除することは一般的ではありませんが、通常は、ユーザビリティテストまたは機能テストが完了した後、クリーンアップするために行います。

以下に、セッションを示す簡単な例を示します。 RootControllerクラスには、セッション変数を設定する* setsession()*メソッドがあります。

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>"
*http://localhost:8080/setsession* と入力します

セッション

ブラウザ内のリンクは、セッション変数を取得して表示する http://localhost:8080/getsession につながります-

変数

TurboGears –キャッシュ

Webアプリケーションのパフォーマンスを向上させるために、特に長時間の操作に関与している場合は、キャッシュ技術が使用されます。 TurboGearsは、2種類のキャッシュ手法を提供します-

全ページキャッシュ

HTTPプロトコルレベルで動作し、ユーザーのブラウザまたは中間プロキシサーバー(Squidなど)がリクエストをインターセプトし、キャッシュされたファイルのコピーを返すことにより、サーバーへのリクエスト全体を回避します。

アプリケーションレベルのキャッシュ

これはアプリケーションサーバー内で機能し、計算された値(多くの場合、複雑なデータベースクエリの結果)をキャッシュします。これにより、将来のリクエストで値を再計算する必要がなくなります。 Webアプリケーションの場合、アプリケーションレベルのキャッシングにより、複雑なクエリの結果を柔軟にキャッシュできるため、特定のコントローラーメソッドの合計負荷をユーザー固有またはケース固有のいくつかのクエリとテンプレートのレンダリングオーバーヘッドに減らすことができます。 。

アプリケーションレベルのキャッシュ

前述のとおり、「クイックスタート」TurboGearsプロジェクトは、キャッシュサポートのためにBeakerパッケージを有効にするように構成されています。 Beakerは、キャッシュストレージに使用される次のバックエンドをサポートしています-

  • memory -プロセスごとのストレージに使用されます。 非常に高速です。
  • filesystem -プロセスごとのストレージおよびマルチプロセス。
  • * DBMデータベース*-プロセスごと、マルチプロセス、かなり高速。
  • * SQLAlchemyデータベース*-データベースサーバーごとのストレージ。 上記のオプションと比較して遅い。
  • Memcached -マルチサーバーメモリベースのキャッシュ。

コントローラーのキャッシュ

コントローラーの迅速なキャッシュのために、* cached()*デコレーターが利用可能です。 リクエストのさまざまなパラメーターに応じて、コントローラー本体全体がキャッシュされます。 * tg.decorators.cached()*デコレータの定義は次のとおりです。

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

パラメータの説明は次のとおりです-

Sr.No. Parameters & Description
1

key

キャッシュキーの生成に使用されるコントローラーパラメーターを指定します。

2

expire

キャッシュが期限切れになるまでの秒単位の時間。デフォルトは「never」です。

3

Type

dbm、memory、file、memcached、またはNone。

4

cache_headers

応答ヘッダーを示すヘッダー名のタプル。

5

invalidate_on_startup

Trueの場合、キャッシュはアプリケーションが起動または再起動されるたびに無効になります。

6

cache_response

応答はキャッシュされるかどうか、デフォルトはTrueです。

以下は、コントローラのキャッシュの例です-

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

テンプレートレベルのキャッシュ

Genshiテンプレートエンジンは、コンテンツが変更されていない場合、キャッシュからテンプレートを取得します。 このキャッシュのデフォルトサイズは25です。 デフォルトでは、テンプレートの自動再ロードはtrueです。 パフォーマンスを改善するために、次の設定を app_cfg.py で行うことができます-

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

テンプレートをキャッシュするには、キャッシュされたテンプレートをレンダリングするコントローラーから tg_cache オプションを返すだけです。

tg_cacheは、次のキーを受け入れる辞書です-

  • key -キャッシュキー。 *デフォルト:*なし。
  • expire -キャッシュが存続する時間。 *デフォルト:*有効期限はありません
  • type -メモリ、dbm、memcached。 デフォルト: dbm。

次の例は、テンプレートのキャッシュを示しています-

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

TurboGears – SQLAlchemy

TurboGearsアプリケーションでSQLを使用してリレーショナルデータベースでCRUD操作を実行することは可能ですが、PythonツールキットはSQLAlchemyを使用することをお勧めします。Pythonツールキットは、アプリケーション開発者にSQLのフルパワーと柔軟性を提供する強力なオブジェクトリレーションマッパーです。 SQLAlchemyによるSQLベースのデータベースのサポートに加えて、TurboGearsはMingを介してMongoDBデータベースもサポートします。 このセクションでは、SQLAlchemyの機能について説明します。

Sql

ORM(オブジェクトリレーショナルマッピング)とは何ですか?

ほとんどのプログラミング言語プラットフォームはオブジェクト指向です。 一方、RDBMSサーバーのデータはテーブルとして保存されます。 オブジェクト関係マッピングは、オブジェクトパラメータを基になるRDBMSテーブル構造にマッピングする手法です。 ORM APIは、生のSQLステートメントを記述することなくCRUD操作を実行するメソッドを提供します。

オーム

ギアボックスツールキットから「クイックスタート」コマンドを使用してTurboGearsプロジェクトを作成すると、SQLAlchemyサポートは次の構成設定によりデフォルトで有効になります-

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

「クイックスタート」プロジェクトは、その中にモデルパッケージも作成します。 たとえば、「He​​llo」プロジェクトにはHello \ hello \ modelがあります。 次のファイルがこのパッケージに作成されます-

  • init。py -これはデータベースアクセスが設定される場所です。 このモジュールには、アプリケーションのモデルオブジェクトがインポートされます。 また、グローバルセッションマネージャーであるDBSessionと、すべてのモデルクラスの基本クラスであるDeclarativeBaseもあります。
  • auth.py -これは、認証スタックで使用されるモデルが定義される場所です。 追加のデータベースモデルは別のモジュールとしてこのパッケージに格納され、init.pyに追加されます。

TurboGears –モデルの作成

*sqlite* データベースに学生テーブルを設定する学生モデルを追加しましょう。
*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 = '')
  • init。py。内の init_model()*関数にこのモデルを追加します。この関数には既に認証モデルが含まれています。 その下に学生モデルを追加します。
# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student

モデルのセットアップ時にテーブルを何らかのデータで初期化する場合は、websetupパッケージのbootstrap.pyに追加します。 * bootstrap()*関数に次のステートメントを追加します。

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

モデルは、ギアボックスのsetup-appコマンドを実行して初期化されます-

gearbox setup-app

SQLAlchemyのSessionオブジェクトは、ORMオブジェクトのすべての永続化操作を管理します。

TurboGears – CRUD操作

次のセッションメソッドはCRUD操作を実行します-

  • * DBSession.add(model object)*-レコードをマップされたテーブルに挿入します。
  • * DBSession.delete(model object)*-テーブルからレコードを削除します。
  • * DBSession.query(model).all()*-テーブルからすべてのレコードを取得します(SELECTクエリに対応)。

フィルター属性を使用して、取得したレコードセットにフィルターを適用できます。 たとえば、studentsテーブルでcity = 'Hyderabad’のレコードを取得するには、次のステートメントを使用します-

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

ここで、コントローラーURLを介してモデルと対話する方法を確認します。

最初に、学生のデータを入力するためのToscaWidgetsフォームを設計しましょう

*Hello \ hello \ controllers.studentform.py*
import tw2.core as twc
import tw2.forms as twf

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

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

RootController(Helloアプリケーションのroot.py)で、次の関数マッピング「/add」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)

次のHTMLコードを studentforml としてテンプレートフォルダーに保存します-

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

サーバーの起動後、ブラウザーに http://localhost:8080/add と入力します。 次の学生情報フォームがブラウザで開きます-

登録

上記のフォームは、 ’/save_record’ URLに送信されるように設計されています。 したがって、* save_record()関数を公開するには、 *root.py に追加する必要があります。 studentformからのデータは、この関数によって* dict()*オブジェクトとして受信されます。 学生モデルの基礎となる学生テーブルに新しいレコードを追加するために使用されます。

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

追加に成功すると、ブラウザは ’/listrec’ URL にリダイレクトされます。 このURLは* listrec()関数*によって公開されます。 この関数は、studentテーブルのすべてのレコードを選択し、dictオブジェクトの形式でstudentlistlテンプレートに送信します。 この* listrec()*関数は次のとおりです-

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

studentlistlテンプレートは、py:forディレクティブを使用して、entries辞書オブジェクトを反復処理します。 studentlistlテンプレートは次のとおりです-

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

ここで http://localhost:8080/add に再度アクセスして、フォームにデータを入力します。 送信ボタンをクリックすると、ブラウザがstudentlistlに移動します。 また、「新しいレコードが正常に追加されました」というメッセージが点滅します。

エントリ

TurboGears – DataGrid

ToscaWidgetsには、データを表形式ですばやく表示するDataGridコントロールが含まれています。 DataGridオブジェクトは次のように宣言されています-

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

現在、showgrid()関数は、studentテーブルのすべてのレコードを取得し、データをgridlテンプレートに公開しています。 最初にshowgrid()関数のコード、次にgridlコードを以下に示します-

showgrid()

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

グリドル

<!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>
*http://localhost:8080/showlist* URLがブラウザに入力されると、次の表形式のデータが表示されます-

フォーム

TurboGears –ページネーション

TurboGearsは、ページの出力を分割するpaginate()と呼ばれる便利なデコレーターを提供します。 このデコレータは、expose()デコレータと組み合わされます。 @Paginate()デコレータは、クエリ結果の辞書オブジェクトを引数として受け取ります。 また、ページあたりのレコード数は、items_per_page属性の値によって決定されます。 tg.decoratorsからコードにpaginate関数をインポートしてください。

次のようにroot.pyのlistrec()関数を書き換えます-

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)

1ページあたりの項目は3つに設定されています。

studentlistlテンプレートでは、py:forディレクティブの下にtmpl_context.paginators.entries.pager()を追加することにより、ページナビゲーションが有効になります。 このテンプレートのコードは次のようになります-

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

ブラウザに http://localhost:8080/listrec と入力します。 テーブル内のレコードの最初のページが表示されます。 この表の上部には、ページ番号へのリンクも表示されます。

記録

ページネーションサポートをDatagridに追加する方法

データグリッドにページネーションのサポートを追加することもできます。 次の例では、ページ分割されたデータグリッドはアクションボタンを表示するように設計されています。 アクションボタンをアクティブにするために、データグリッドオブジェクトは次のコードで構築されます-

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

ここで、アクションボタンは、データグリッドの各行の名前パラメーターにリンクされています。

次のように* showgrid()*関数を書き直します-

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

ブラウザには、ページ分割されたデータグリッドが次のように表示されます-

登録フォーム

3行目の[編集]ボタンをクリックすると、次のURLにリダイレクトされます http://localhost:8080/edit?name = Rajesh + Patil

TurboGears –管理者アクセス

TurboGearsは、tgext.crudおよびsproxを使用したtgext.admin拡張機能を提供します。 このSproxは、データベーススキーマから直接Webウィジェットを作成するために使用されるパッケージです。 これは、単純な管理ページを自動的に作成するために使用でき、新しくクイックスタートされたアプリケーションの/adminページを強化するツールキットです。

デフォルトでは、管理者はプロジェクトmodels/init.pyにインポートされたすべてのモデルへの自動生成されたアクセスを提供します。

TurboGears Adminを作成する方法

デフォルトのTurboGears管理者は、AdminControllerクラスのオブジェクトとして作成されます-

from tgext.admin.controller import AdminController

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

これにより、デフォルトのTurboGears管理設定を使用して、すべてのモデルの管理者が作成されます。

マネージャーを通じて、セットアップ段階でユーザーが作成されました。 これで、 http://localhost:8080/admin でTurboGears Adminにアクセスできるようになりました。このページに初めてアクセスすると、認証を求められます。 あなたは単にsetup-appコマンドが私たちのために作成したユーザーのユーザー名とパスワードを提供することができます-

Username: manager
Password: managepass

クイックスタートされたプロジェクトにログインするには、次の関数を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)

サーバーの起動後、 http://localhost:8080/login にアクセスして「quickstarted」アプリケーションにログインし、上記のようにマネージャーの資格情報を入力します。 ブラウザには、以下に示すような管理ページが表示されます-

管理パッド

ページには、このアプリケーションで作成されたすべてのモデルが表示されます。 あなたは、その中のエントリのリストを見るために、任意のモデルをクリックすることができます-

学生リスト

このデータグリッドの上部にある「新規」ボタンを使用すると、レコードを追加できます。 同様に、レコードを編集および削除するためのアクションボタンも、このデータグリッドのアクション列に用意されています。 レコードを条件付きで選択するための検索ボックスも表示されます。

DataGrid

TurboGears –認証と認証

TurboGearsアプリケーションは、ギアボックスツールキットのクイックスタートオプションとsetup-appオプションによって作成されます。ギアキットツールキットには、既定で認証と認証のサポートが有効になっています。 auth.pyで宣言されたモデルは、bootstrap.pyで割り当てられた値に従って設定および初期化されます。

次のモデルはauth.pyで宣言されています-

ユーザーモデル

Userモデルには、tg_userテーブルの設計が含まれています。 このテーブルは、repose.whoパッケージで使用されます。 このrepose.whoパッケージは強力で、WSGIアプリケーション用の拡張可能な認証ライブラリです。 ユーザーモデルの構造は次のとおりです-

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)

このグループモデルには、定義tg_groupテーブルが含まれます。 その定義は次のようにauth.pyで与えられています-

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)

権限の定義を含む別のモデル権限も設定されます。

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

モデルのセットアップ時に、次のデータがこれらのテーブルに追加されます-

u = model.User()
u.user_name = 'manager'
u.display_name = 'Example manager'
u.email_address = 'manager@somedomain.com'
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 = 'editor@somedomain.com'
u1.password = 'editpass'

model.DBSession.add(u1)

述語モデル

tgパッケージの述語モジュールには、述語チェッカーの定義が含まれています。 述語とは、ユーザーが要求されたソースにアクセスできるために満たす必要がある条件です。 このような述語または条件は、より多くの述語で構成されている場合があります。これらは複合述語と呼ばれます。 アクションコントローラー、またはコントローラーには、単一または複合の1つの述語のみがあります。

ユーザーがログインしていない場合、または適切な権限がない場合、この述語チェッカーは401(HTTP Unauthorized)をスローします。これはrepoze.whoミドルウェアによってキャッチされ、ログインページを表示して、ユーザーがログインし、完了したら、ユーザーは適切なページに戻ります。

tg.predicatesモジュールで定義されているさまざまな条件または述語は-

Sr.No. tg.predicates module & Description
1

All

指定されたすべての述語が満たされているかどうかを確認します

2

Any''''

指定された述語の少なくとも1つが満たされているかどうかを確認します

3

is_user

認証されたユーザーのユーザー名が指定されたものであることを確認してください

4

in_group

ユーザーが特定のグループに属していることを確認してください。

5

in_all_groups

ユーザーが指定されたすべてのグループに属していることを確認してください。

6

in_any_group

指定されたグループの少なくとも1つにユーザーが属していることを確認してください。

7

is_anonymous

現在のユーザーが匿名であることを確認してください。

8

has_permission

現在のユーザーが指定された権限を持っていることを確認してください。

9

has_all_permissions

現在のユーザーに、指定されたすべての権限が付与されていることを確認してください。

10

has_any_permission

ユーザーが指定された許可の少なくとも1つを持っていることを確認してください。

たとえば、*顧客グループに属するアクセス権を付与する*述語がある場合は、次の組み込み述語チェッカーを使用できます-

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

次の述語チェッカーは、「root」ユーザーまたは「manage」権限を持つユーザーにアクセスを許可します-

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

TurboGears-MongoDBの使用

TurboGearsは、MongoDBドキュメントデータベースもサポートしています。 オブジェクトドキュメントマッパーAPIであるMing​​を使用します。 Mingの使用法はSQLAlchemyと非常によく似ています。 Mingクエリ言語により、SQLAlchemyベースのTurboGearsプロジェクトをMingに移植できます。

PyMongoとは

PyMongoは、MongoDBを操作するためのツールを含むPythonディストリビューションです。 MingはPyMongoを拡張して以下を提供します-

  • 宣言的モデル
  • スキーマの検証と変換
  • スキーマの進化
  • 純粋なInMemory MongoDBの実装
  • 作業単位
  • アイデンティティマップ
  • 1対多、多対1および多対多の関係

まず、MongoDBをダウンロードしてインストールする必要があります。 MongoDBの最新のディストリビューションは、https://www.mongodb.org/downloads#production [https://www.mongodb.org/downloads]からダウンロードできます。

Windowsでは、-dbpathオプションを指定してMongoDBサーバーを起動します-

C:\mongodb\bin>Mongod --dbpath d:\mongo
*D:\ mongo folder* は、MongoDBデータベースを保存するために指定されています。 サーバーは* http://localhost:27017でリッスンを開始します。* MongoDBシェルを開始するには、次のコマンドを使用します-
C:\mongodb\bin>Mongo

これで、MongoDB環境の準備が整いました。

-mingオプションを使用してTurboGearsプロジェクトを作成します-

gearbox quickstart --ming Hello

このクイックスタートプロジェクトは、SQLAlchemyバージョン用に提供されているような認証および承認レイヤーを提供します。 このアプリケーションは、ローカルマシンのポート27017でサーバーに接続しようとします。 プロジェクトフォルダ内のdevelopment.iniファイルには、次の設定が含まれています-

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

次のコマンドを使用してプロジェクトを設定します-

Python setup.py develop

プロジェクトフォルダには、次のファイルを持つモデルサブフォルダが含まれています-

  • _ init。py_ -これは、*データベース*アクセスが設定される場所です。 コレクションを*このモジュールにインポート*する必要があります。 たとえば、このパッケージに学生コレクションを追加します。
  • session.py -このファイルは、データベース接続のセッションを定義します*。 クエリを実行するセッションを指定するために *MappedClass を宣言する必要があるたびに、これをインポートする必要があります。
  • auth.py -クイックスタートで認証と承認*を有効にしている場合、このファイルが作成されます。 これは、3つのコレクション repoze .whoを定義します。これは、ユーザー、グループ、および許可にさらに依存します。

コレクションを定義する

デフォルトでは、TurboGearsはMingを宣言モードで構成します。 これは、SQLAlchemyの宣言サポートに似ており、MappedClassクラスから継承する各モデルが必要です。

MappedClassでは、mongometaサブクラスが内部で使用可能である必要があります。これにより、ドキュメントを保存するコレクションの名前とドキュメントの保存に使用されるセッションに関する詳細が提供されます。

MappedClassには、ドキュメント内のフィールドの定義も含まれています。 Mingのodmモジュールには、さまざまなタイプのフィールドプロパティの定義があります-

  • FieldProperty
  • ForeignIdProperty
  • RelationProperty
  • ming.schemaモジュール*は、次のデータ型を定義します-
  • 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

このモデルに生徒のコレクションを追加するには、hello/modelsフォルダーに次のコードをstudent.pyとして保存します。

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

最後に、このモデルをhello \ models \ init.pyに含めます

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

これらのモデルをセットアップするには、次のギアボックスコマンドを実行します-

Gearbox setup-app

次のギアボックスコマンドでサーバーを起動します-

Gearbox serve –reload –debug

このアプリケーションのホームページ*(http://localhost:8080/)*を開き、マネージャーの資格情報でログインします。 このアプリケーションの管理ページには、セットアップされたモデルのリストが表示されます。 (マネージャーとしてログイン、パスワードmanagepass)

ホームページアプリケーション

コレクションの作成は、MongoDB WebインターフェイスとMongoDBシェルでも確認できます。

ODMSessionは、次の機能を使用していくつかのデータベース操作を実行するために使用されます-

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

ToscoWidgetフォームの設計

ToscoWidgetフォームを設計して、学生データを入力し、学生モデルの基礎となるテーブルに追加します。

以下は、studentform.pyを作成するためのコードです-

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

add()関数を呼び出すアプリケーションのRootcontroller '/add' URLで、ブラウザーで上記の設計されたフォームを開きます。 次に、その送信ボタンはsave_record()関数を呼び出します。 フォームデータを取得し、それを学生テーブルに保存し、アプリケーションを '/listrec' URLにリダイレクトします。これにより、studentlistテンプレートが公開されます。

このアクティビティのroot.pyは次のとおりです-

こんにちは/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")

次のテンプレートがテンプレートフォルダに作成されます-

こんにちは\テンプレート\学生フォーム

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

Hello \ templates \ studentlistl

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

サーバーを再起動し、ブラウザに http://localhost:8080/add と入力します-

学生登録フォーム

データが追加され、送信ボタンが押されるたびに、現在のエントリのリストが表示されます。

新しいエントリ出力

TurboGears –足場

Gearboxツールキットにはscaffoldコマンドが含まれており、TurboGearsアプリケーションの新しいコンポーネントをすばやく作成するのに非常に便利です。 gearboxのクイックスタートコマンドで生成されたアプリケーションには、モデルフォルダー(model.py.template)、テンプレートフォルダー(templatel.template)、コントローラーフォルダー(controller.py.template)にスケルトンテンプレートがあります。 これらの「.template」ファイルは、アプリケーションの新しい足場を作成するための基礎として使用されます

たとえば、mymodelという名前の新しいモデルを作成するには、単に次のコマンドを実行します-

gearbox scaffold model mymodel

このコマンドは、newmodelクラスが定義されたmodel/mymodel.pyを生成します。

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

ユーザーは、必要に応じてテーブル構造を変更し、それを model/init。py 内にインポートして、モデルをアプリケーション内で使用できるようにすることができます。

モデルを作成するには、次のコマンドを使用して、モデルを処理するコントローラークラスとこれら3つのコンポーネントすべてを同時に作成できます。

gearbox scaffold model controller template mymodel

このコマンドの結果、controllers \ mymodel.pyにMymodelControllerクラスが適切に定義されます。

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

このコントローラーの使用を開始するには、MymodelControllerのインスタンスを定義するためだけに、アプリケーションRootController内にマウントします。 controllers \ root.pyにこれらの行を追加します-

From hello.controller.mymodel import MymodelController

class RootController(BaseController): mymodel = MymodelController()

テンプレートのscaffold templates \ mymodellも、templatesフォルダーに作成されます。 「/mymodel」URLのインデックスページとして機能します。

テンプレートフォルダに生成された* mymodellファイル*は次のようになります-

<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 = "masterl"/>

   <head>
      <title>Mymodel</title>
   </head>

   <body>
      <div class = "row">
         <div class = "col-md-12">
            <h2>Mymodel</h2>
            <p>Template page for Mymodel</p>
         </div>
      </div>
   </body>

</html>

TurboGears –フック

TurboGearsには、既存のアプリケーション内で動作をプラグインする3つの方法があります。

  • フック-これは、イベントを定義し、登録されたリスナーにイベントが発行されたときに通知するメカニズムです。
  • Controller Wrapper -TurboGearsとControllerの間に位置するため、コントローラーをデコレータのように拡張できます。 したがって、任意のサードパーティ製コントローラーアプリケーションに接続できます。
  • アプリケーションラッパー-WSGIミドルウェアに似ていますが、TurboGearsコンテキストでのみ動作します。

この章では、既存のアプリケーション内でフックを使用する方法について説明します。

フック

フックは、アプリケーションの構成ファイル app_cfg.py に登録されたイベントです。 次に、イベントデコレータによってこれらのイベントにコントローラがフックされます。

次のフックはTurboGearsで定義されています-

Sr.No. Hooks & Description
1

Startup()

アプリケーション全体のみ。アプリケーションの起動時に呼び出されます。

2

shutdown()

アプリケーション全体のみ。アプリケーションの終了時に呼び出されます。

3

configure_new_app

新しいアプリケーションは、アプリケーションコンフィギュレータによって作成されました。

4

before_config(app)

アプリケーション全体のみ。アプリケーションの作成直後、ただしオプションとミドルウェアをセットアップする前に呼び出されます

5

after_config(app)

アプリケーション全体でのみ、すべての設定が完了した後に呼び出されます。

6

before_validate

検証を実行する前に呼び出されます

7

before_call

検証後、実際のコントローラーメソッドを呼び出す前に呼び出されます。

8

before_render

コントローラーテンプレートをレンダリングする前に呼び出され、出力はコントローラーの戻り値です。

9

after_render

コントローラーテンプレートのレンダリングが完了した後に呼び出されます。

フックを登録する

フックを登録するには、 app_cfg.py に関数を作成し、次のコードを使用して登録します-

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

次のコードでは、on_startup、on_shutdown、before_renderフックが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)

before_renderフックは、Rootcontrollerのコントローラー関数に登録されます。 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')

アプリケーションが提供されると、コンソールに起動メッセージが表示されます。

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

ブラウザに「/」URLが入力されると、before_renderフックに対応するメッセージがコンソールに表示されます。

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

TurboGears-拡張機能の作成

TurboGears拡張機能は、* tgext。*パッケージ*で識別されます。 Gearboxツールキットには、サンプル拡張機能を作成するtgextコマンドが用意されています。 たとえば-

gearbox tgext -n myextension

このコマンドの他のオプションのパラメータは-

  • *-author *-パッケージ作成者の名前。
  • *-email *-パッケージ作成者の電子メール。
  • *-licence *-パッケージに使用されるライセンス。 デフォルトはMITです。
  • *-description *-パッケージの説明。
  • *-keywords *-パッケージのキーワード(デフォルト:turbogears2.extension)。

これにより、tgext.myextensionディレクトリが作成されます。このディレクトリには、簡単なサンプル拡張機能が含まれています。

  • ディレクトリ内でsetup.py *を実行します-
Python setup.py install
*tgext/myextension* フォルダー内の *_init_.py* ファイルには以下が含まれます-
  • プラグイン機能-これは、拡張のエントリポイントです。

  • * SetupExtensionクラス*-拡張機能の初期化はここで行われます。

  • * On_startup関数*-クラス内は、クラス内のcall関数に登録されたフックです。

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

拡張機能をインストールしたら、アプリケーションの app_cfg.py 構成ファイルに次の追加を行って、拡張機能を有効にします。

from tgext.myextension import plugme

plugme(base_config)

ギアボックスサーバーコマンドを使用してサーバーを起動した場合、新しく登録された拡張機能の通知は、次のようにコンソールで表示できます-

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

TurboGears-プラグ可能なアプリケーション

拡張機能でモデルとコントローラーを公開する必要がある場合は、他のアプリケーションにプラグインして機能を拡張できる再利用可能なTurbogearsアプリケーションを作成する Pluggable Applications をご覧ください。

次のギアボックスコマンドを使用して、プラグ可能なアプリケーションを作成します-

gearbox quickstart-pluggable plugtest

これらのプラグ可能なアプリケーションは、独自に定義することができます-

  • Controllers -アプリケーションが削除されると、自動的にマウントされます。
  • モデル-プラグインされたアプリケーションの内外で利用可能になります。
  • ヘルパー-アプリケーションテンプレートの「H」オブジェクトで自動的に公開できます。
  • Bootstrap -setup-appが呼び出されたときに実行されます。
  • Statics -独自のプライベートパスで利用可能になります。

このプラグテストアプリケーションをインストールし、 app_cfg.py で次の変更を加えて同じものをマウントします。

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

TurboGears – RESTfulアプリケーション

RESTは* RE presentational S tate T * ransferの略です。 RESTはWeb標準ベースのアーキテクチャであり、データ通信にHTTPプロトコルを使用します。 すべてのコンポーネントがリソースであり、リソースがHTTP標準メソッドを使用して共通のインターフェイスによってアクセスされるリソースを中心に展開します。 RESTは、2000年に* Roy Fieldingによって初めて導入されました。

RestControllerとは

TurboGearsのRestControllerは、URLだけでなく、リクエストのメソッドにアクセスするメカニズムを提供します。 標準のHTTP表現には、GET、POST、PUT、およびDELETEが含まれます。 RestControllerはこれらをサポートし、データをフォームやリストとして表示するURLディスパッチのショートカットをいくつか追加します。これはユーザーにとって少し簡単です。

RESTfulがTurboGearsでどのように機能するかを説明するために、学生のリストを公開する簡単なWebサービスを定義します。

学生モデルのコードは以下のとおりです-

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

次に、RestControllerに基づいてコントローラーを作成し、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)

次の行を root.py に組み込むことにより、このStudentControllerをアプリケーションのRootControllerにマウントします−

from hello.controllers.student import StudentController

class RootController(BaseController):

   students = StudentController()
*http://localhost:8080/students* にアクセスすると、json形式でエンコードされた生徒のリストが表示されます。

postメソッドを使用して、学生をデータベースに保存する方法を定義します。 このメソッドは、 http://localhost:8080/student のURLが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)
  • get_one()*メソッドを使用して、データベースからユーザーに1つのアイテムを表示できます-
@expose('json')
def get_one(self, movie_id):
   newstudent = DBSession.query(student).get(uid)
   return dict(movie = movie)

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

削除の主力はpost_deleteメソッドに付加されます。 ここでは、実際にデータベースからレコードを削除してから、リストページにリダイレクトします-

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

TurboGears-展開

開発環境から本格的な本番環境に切り替えるには、アプリケーションを実際のWebサーバーにデプロイする必要があります。 使用しているものに応じて、TurboGears Webアプリケーションを展開するために使用できるさまざまなオプションがあります。

mod_wsgiを使用したApache

mod_wsgiは、Graham Dumpletonによって開発されたApacheモジュールです。 Apache Webサーバーを使用してWSGIプログラムを提供できます。

まず、プラットフォームにApache 2.Xをインストールします(まだインストールされていない場合)。 Apacheをインストールしたら、mod_wsgiをインストールします。 サーバーでPython仮想環境を作成してアクティブ化し、TurboGearsをインストールします。

アプリケーションディレクタ内にアプリケーションをインストールし、 app.wsgi という名前のスクリプトを作成します。

次のようにApacheのインストールを設定します-

<VirtualHost *:80>
   ServerName www.site1.com
   WSGIProcessGroup www.site1.com
   WSGIDaemonProcess www.site1.com user = <username>
      group = www-data threads = 4 python-path = <pythonpath>
   WSGIScriptAlias myapp/app.wsgi

   #Serve static files directly without TurboGears
   Alias/images
   Alias/css
   Alias/js
   CustomLog
   ErrorLog
</VirtualHost>

Apacheを再起動します

ブラウザで* http://www.site1.com/*と入力して、アプリケーションにアクセスします。

サーカスとショーセットの下のターボギア

Circusはプロセス&ソケットマネージャーです。 プロセスとソケットの監視と制御に使用できます。 Chaussette WSGIサーバーと組み合わせると、アプリケーションをデプロイし、アプリケーションに必要な関連プロセスを管理するための強力なツールになります。

TurboGears-GoogleAppEngine

Python用Google AppEngine SDKを次のURLからインストールします-https://cloud.google.com/appengine/downloads[https://cloud.google.coms]

システムにGoogle AppEngineをインストールします。 次に、Googleデベロッパーコンソールを開き、Googleアカウントでログインします-https://console.developers.google.com/start

*mytgapp* という新しいプロジェクトを作成します-

Mytgappプロジェクト

Google AppEngine Launcherを使用して、* mytgapp。*という名前の新しいアプリケーションを作成します

新しいアプリケーション

Google App Engine Launcher

次のファイルが指定されたディレクトリに作成されます-

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

デフォルトでは、作成されたアプリケーションはWebapp2フレームワークに依存しています。 この依存関係を削除するには、app.yamlファイルを編集し、次の部分を削除します-

libraries:
   - name: webapp2
   version: "2.5.2"

mytgappという名前のディレクトリに一時的な仮想環境を作成し、TurboGearsをインストールします。 TurboGearsアプリケーションを作成します。 これで、AppEngineによって起動された main.py ファイルの編集を進めて、アプリケーションを実行し、実際にTurboGearsアプリケーションを作成できます。

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

AppEngine Launcherからアプリケーションを実行し、参照ボタンをクリックして、ローカルホストでアプリケーションが適切に動作することを確認します。

開発者コンソールでmytgappという名前のプロジェクトを既に作成しました。 ランチャーのデプロイボタンをクリックします。 展開プロセスが終了したら、* http://mytgapp.appspot.com/*にアクセスして、オンラインでアプリケーションを表示します。

mytgapp appspot