Turbogears-クイックガイド

Webフレームワークとは何ですか?

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

TurboGearsとは何ですか?

TurboGearsは、Pythonで記述されたWebアプリケーションフレームワークです。2005年にKevinDangoorによって最初に作成された最新バージョンのTurboGears(ver 2.3.7)は、MarkRammとFlorentAideが率いる開発者グループによって管理されています。

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

Model View Controller

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

  • Model −パターンの最低レベルは、データの維持を担当します。

  • View −これは、データのすべてまたは一部をユーザーに表示する責任があります。

  • Controller −モデルとビュー間の相互作用を制御するソフトウェアコード。

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

モデル

モデルは、アプリケーションのデータを管理する責任があります。ビューからの要求に応答し、コントローラーからの指示にも応答して自身を更新します。

景色

データを提示するというコントローラーの決定によってトリガーされる、特定の形式でのデータの提示。これらは、AJAXテクノロジーとの統合が非常に簡単なスクリプトベースのテンプレートシステムです。

コントローラー

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

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

SQLAlchemy

これは、Pythonコードのオブジェクト関係マッピング(ORM)を提供するオープンソースのSQLキットです。

源氏

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

ToscaWidgets

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

ギアボックス

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

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

前提条件

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

次のコマンド installs virtualenv

pip install virtualenv

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

Sudo apt-get install virtualenv

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

mkdir newproj
cd newproj
virtualenv venv

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

venv/bin/activate

オン Windows

venv\scripts\activate

これで準備が整いました install TurboGearsこの環境で。TurboGearsの最小限のインストールは、次のコマンドで実行されます-

pip install TurboGears2

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

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

pip install tg.devtools

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

TGアプリケーションのアプリケーションクラスはから継承されます TGControllerクラス。このクラスのメソッドは、次の方法でアクセスできます。@expose デコレータ tgモジュール。最初のアプリケーションでは、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サーバーを起動する必要があります。前述のように、simple_server のモジュール wsgirefセットアップして起動するパッケージ。このモジュールにはmake_server() ポート番号とアプリケーションオブジェクトを引数として必要とするメソッド。

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

これは、アプリケーションがlocalhostのポート番号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 ブラウザのアドレスバーに「HelloWorldTurboGears」メッセージを表示します。

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

gearbox quickstart HelloWorld

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

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

  • Config −プロジェクトのセットアップと構成が依存する場所

  • Controllers −すべてのプロジェクトコントローラー、Webアプリケーションのロジック

  • i018n −サポートされている言語の翻訳ファイル

  • Lib −ユーティリティpython関数とクラス

  • Model −データベースモデル

  • Public Static Files − CSS、JavaScript、画像

  • Templates −コントローラーによって公開されたテンプレート。

  • Tests −実行された一連のテスト。

  • Websetup −アプリケーションのセットアップ時に実行する機能。

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

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

Python setup.py develop

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

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

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

Gearbox serve –reload –debug

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

このハロープロジェクトでは、デフォルトのコントローラーがコントローラーディレクトリに次のように作成されます。 Hello/hello/controllers.root.py。私たちにさせてmodify 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からパラメーターとして名前を受け入れるように設計されています。

'gearboxserve'コマンドでサーバーを起動した後、 http://localhost:8080。次のURLを入力しても、HelloWorldメッセージがブラウザに表示されます-

http://localhost:8080/

http://localhost:8080/index

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

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

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

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

Hello MVL

TurboGearsは、URLパラメーターを関数の引数に自動的にマップします。RootControllerクラスはBaseControllerから継承されます。これは次のように定義されますbase.py の中に lib folder アプリケーションの。

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

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メソッドにディスパッチします。

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

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

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

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

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

私たちの sample.html以下に示します。プロジェクトのテンプレートディレクトリに保存されていることを確認してください。

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

追加 sample() で機能する root.py そしてそれを通してsample.htmlを公開します。

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

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

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

変更しましょう sample() 辞書オブジェクトをサンプルテンプレートに送信する関数。

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

作成する sample.html テンプレートフォルダ内(templates\sample.html

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

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

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

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

シニア番号 HTTPメソッドと説明
1

GET

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

2

HEAD

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

3

POST

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

4

PUT

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

5

DELETE

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

HTMLフォームの作成

HTMLフォームを作成し、フォームデータをURLに送信しましょう。次のスクリプトを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>

このフォームに入力されたデータは、 ‘/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}

ご覧のとおり、ログインフォームから受信したデータはsample.htmlテンプレート(先ほど使用)に送信されています。それはによって解析されますGenshi template engine 次の出力を生成するには-

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() コントローラはフォームデータを受信し、に送信します sample.htmlテンプレート。のコード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

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

<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 ブラウザで

ザ・ sample.html 次の出力をレンダリングします-

GenshiはXMLベースのテンプレート言語です。に似ていますKid、以前のバージョンのTurboGearsのテンプレートエンジンでした。GenshiとKidは、次のような他の有名なテンプレート言語に触発されていますHSLT, TAL そして PHP

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ではいくつかのディレクティブが定義されています。次のリストはGenshiディレクティブを列挙しています-

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

条件付きセクション

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

py:if

このディレクティブの要素の内容は、次の式の場合にのみレンダリングされます。 if clausetrueと評価されます。テンプレートコンテキストのデータが{‘foo’:True, ‘bar’:’Hello’}、次のディレクティブ-

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

結果として

Hello

ただし、この出力は次の場合にはレンダリングされません。 ‘foo’ is set to False

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

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

py:choose

高度な条件付き処理は、 py:choose と組み合わせて py:when そして py:otherwiseディレクティブ。この機能はに似ていますswitch – case で構築する C/C++

での表現 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フォームはデータを/ marksURLに投稿します。ザ・marks() 関数は、マークと結果を辞書オブジェクトの形式でにリダイレクトします total.htmlテンプレート。の条件付き表示result Pass/Fail を使用して達成されます py:choose そして py:when ディレクティブ。

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

<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() コントローラーはマークと結果をに送信しています total.html テンプレート-

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

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

ザ・ total.html テンプレートフォルダ内で辞書データを受け取り、次のように条件付きで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ディレクティブを使用してtotal.htmlテンプレートでレンダリングされた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})

temp.htmlテンプレートは、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>

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

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

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

<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()コントローラーは、name、phy、およびmathsキーを持つ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}

テンプレートmacro.htmlは、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: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>

別の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 = "somepage.html" />

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

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

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

見出しとフッターのHTML

include.htmlでは、include名前空間が宣言され、heading.htmlとfooter.htmlのコンテンツが追加されます。これがtemplates \ include.htmlの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>

これがtemplates \ heading.htmlコードです-

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

以下はtemplates \ footer.htmlです。

<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 = “main.html”>
   <xi:fallback href = ”default.html”/>
</xi.include>

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

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

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

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

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

サーバーを起動する前に、templatesフォルダーにheading.html、main.html、およびfooter.htmlがあることを確認してください。入るhttp://localhost:8082/refinclude 次の出力を取得するには、ブラウザで

ザ・ @expose()デコレータはデフォルトでhtmlコンテンツをレンダリングします。ただし、これはに設定できますjson content type。TurboGearsはjsonレンダリングをサポートしていますtg.jsonify.JSONEncoder (**kwargs)クラス。jsonデータをレンダリングするには、コンテンツタイプとしてjsonを渡すだけで、デコレータが公開されます。

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

'/ jsondata' URLをブラウザに入力すると、-が表示されて応答します。

{"hello": "World"}

jsonpレンダリング

jsonpは、パディング付きのjsonの略です。これは、コントローラーによって返されるすべての値を関数の引数として提供するjavascript関数の呼び出しでapplication / 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"});

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

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

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

Note −これらのテンプレートはサブフォルダ内に配置されます−テンプレート/ブログ

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()関数を呼び出します。

blog.htmlとpost.htmlのコードは以下の通りです-

Blog.html

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

post.html

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

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

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

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

サーバーサイドスクリプトは、httpリクエストデータからフォーム要素を再作成する必要があります。したがって、この効果では、フォーム要素を2回定義する必要があります。1回はHTMLで、もう1回はサーバーサイドスクリプトで定義します。

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

ToscaWidgets2

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

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

  • tw2.core−コア機能を提供します。このモジュールのウィジェットは、エンドユーザーが利用できるようにするためのものではありません。

  • tw2.forms−これは基本的なフォームライブラリです。これには、フィールド、フィールドセット、およびフォームのウィジェットが含まれています。

  • tw2.dynforms −これには動的フォーム機能が含まれています。

  • tw2.sqla −これはSQLAlchemyデータベースのインターフェースです。

tw2.forms

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

シニア番号 フィールドと説明
1

TextField

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

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と呼ばれます。optionsパラメータに対応するListオブジェクトの項目は、ドロップダウンリストを形成します。表示されるキャプションは、prompt_textパラメーターの値として設定されます。

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

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

twf.SubmitButton(value = 'Submit')

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

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

このコードを以下のように保存します twform.html テンプレートディレクトリ内-

<!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クラスには、 stipulated/save_formアクションURLとして。したがって、追加しますsave_form() RootControllerの関数。

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

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

送信ボタンを押すと、このデータがに投稿されます save_form() URL。ディクショナリオブジェクトの形式でフォームデータを表示します。

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

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

ToscaWidgetsフォームライブラリの初期バージョンは、検証サポートをFormEncodeモジュールに依存していました。ToscaWidgets2には、tw2.coreモジュールで利用可能な組み込みの検証サポートがあります。ただし、FormEncode検証手法を使用することは可能です。

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

@validate(form, error_handler, validators)
  • ザ・ ’form’ 検証されるToscaWidgetsフォームオブジェクトです。

  • ザ・ ‘error-handler’ フォームエラーを処理するために使用されるコントローラーメソッドです。

  • ザ・ ‘validators’ FormEncodeバリデーターを含むディクショナリオブジェクトです。

バリデーターの種類

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

LengthValidator−値の長さが規定されているか確認してください。最小および最大制限は、最小および最大パラメーターで定義されます。最小値と最大値の上下の長さのカスタムメッセージは、短すぎるおよびツールオンパラメータとして指定できます。

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

RangeValidator−通常はRangeFieldと一緒に使用されます。最小および最大制限内の数値フィールドの値を検証すると便利です。短すぎるパラメータとツールオンパラメータのメッセージはカスタマイズできます。

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−ユーザー入力が有効な日付であることを確認するのに非常に役立ちます。日付形式(デフォルトはYMD)とエラーメッセージはカスタマイズ可能です。最小および最大の日付制限も指定できます。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−一方のフィールドの値がもう一方のフィールドと一致するかどうかを確認します。これは、ユーザーがパスワードフィールドを選択して確認する必要がある場合に特に便利です。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は、拡張可能なCompoundValidatorのサブクラスであるAnyおよびAllバリデーターを提供します。

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

ザ・ render()TGFlashクラスのメソッドは、Python自体から使用する場合、テンプレートから呼び出してフラッシュメッセージをレンダリングできます。JavaScriptで使用すると、WebFlashオブジェクトが提供されます。露出しますpayload() そして render() 現在のフラッシュメッセージをフェッチしてJavaScriptからレンダリングするメソッド。

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

<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オブジェクトであり、これを含めることにより、レンダリングされたテンプレート内で使用できます。 master.htmlテンプレート。このオブジェクトは、現在のフラッシュメッセージを取得して表示することを許可します。

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

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フォルダー内)で実行できます。設定可能なパラメータは次のとおりです。

シニア番号 パラメータと説明
1

flash.cookie_name

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

2

flash.default_status

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

3

flash.template

として使用 flash template レンダリングされたとき。

4

flash.allow_html

ターン on/off escaping in flash messages、デフォルトではHTMLは許可されていません。

5

flash.js_call

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

6

flash.js_template

string.Template フラッシュメッセージの完全なJavaScriptサポートを置き換えるために使用されるインスタンス。

  • pop_payload() −機能 fetches current flash message, statusおよび関連情報。フラッシュメッセージを取得すると、Cookieが削除されます。

  • render(container_id, use_js=True) −テンプレート内でフラッシュメッセージをレンダリングするか、Javascriptサポートを提供します。

  • container_id はメッセージが表示されるDIVであり、use_jsはフラッシュをHTMLとしてレンダリングするかJavaScriptで使用するかを切り替えます。

  • status −現在のフラッシュステータスのみを取得します。フラッシュステータスを取得すると、Cookieが削除されます。

  • message −現在のフラッシュメッセージのみを取得します。フラッシュメッセージを取得すると、Cookieが削除されます。

簡単なフラッシュメッセージを作成する方法は?

次の例では、flash()メソッドがルートコントローラークラスで提供されています。公開されたテンプレートflash.htmlにレンダリングされる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 {}

作成するためのコード flash.html テンプレートフォルダ内は次のとおりです

<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のsessiondataは、ファイルシステム、データベース、またはハッシュされた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 セッション変数を取得して表示します-

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

Whole-page Caching

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

Application-level Caching

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

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

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

  • memory−プロセスごとのストレージに使用されます。非常に高速です。

  • filesystem −プロセスごとのストレージとマルチプロセス。

  • DBM database −プロセスごと、マルチプロセス、かなり高速。

  • SQLAlchemy database−データベースサーバーごとのストレージ。上記のオプションに比べて遅い。

  • Memcached −マルチサーバーメモリベースのキャッシュ。

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

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

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

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

シニア番号 パラメータと説明
1

key

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

2

expire

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

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 −キャッシュキー。 Default: なし。

  • expire −キャッシュが存続しなければならない期間。 Default: 期限切れになることはありません

  • type −メモリ、dbm、memcached。 Default: dbm。

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

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

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

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

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

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

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

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

  • __init__.py−ここでデータベースアクセスが設定されます。アプリケーションのモデルオブジェクトは、このモジュールにインポートされます。また、DBSession(グローバルセッションマネージャー)と、すべてのモデルクラスの基本クラスであるDeclarativeBaseもあります。

  • auth.py−ここで、認証スタックで使用されるモデルが定義されます。追加のデータベースモデルは、このパッケージに個別のモジュールとして保存され、__init__。pyに追加されます。

学生テーブルを設定する学生モデルを追加しましょう 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_model() 内部の機能 __init__.py.この関数には、すでに認証モデルが含まれています。その下に学生モデルを追加します。

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

モデルは、gearbox −のsetup-appコマンドを実行して初期化されます。

gearbox setup-app

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

次のセッションメソッドは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コードを次のように保存します 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>

入る 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() function。この関数は、studentテーブル内のすべてのレコードを選択し、それらをdictオブジェクトの形式でstudentlist.htmlテンプレートに送信します。このlistrec() 機能は以下の通りです−

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

studentlist.htmlテンプレートは、py:forディレクティブを使用してエントリディクショナリオブジェクトを反復処理します。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>

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

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

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

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

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>

以下の表形式のデータは、次の場合に表示されます。 http://localhost:8080/showlist ブラウザにURLを入力-

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

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に設定されています。

studentlist.htmlテンプレートでは、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ブラウザで。テーブルのレコードの最初のページが表示されます。この表の上に、ページ番号へのリンクも表示されます。

データグリッドにページネーションサポートを追加する方法

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

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

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

TurboGears管理者を作成する方法

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

from tgext.admin.controller import AdminController

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

これにより、デフォルトのTurboGears管理者構成ですべてのモデルの管理者が作成されます。

マネージャを介して、セットアップフェーズ中にユーザーが作成されました。これで、TurboGearsAdminにアクセスできるようになりました。http://localhost:8080/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次に、上記のようにマネージャーの資格情報を入力します。ブラウザに以下のような管理ページが表示されます-

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

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

TurboGearsアプリケーションは、ギアボックスツールキットのクイックスタートおよびセットアップアプリオプションによって作成されます。このオプションでは、承認と認証のサポートがデフォルトで有効になっています。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 = '[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)

述語モデル

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

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

tg.predicatesモジュールで定義されているさまざまな条件または述語は次のとおりです。

シニア番号 tg.predicatesモジュールと説明
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つを持っていることを確認してください。

たとえば、述語がある場合、 grant access user belonging to customers group、次に、次の組み込み述語チェッカーを使用できます-

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ドキュメントデータベースもサポートしています。Object Document MapperAPIであるMing​​を使用します。Mingの使用法はSQLAlchemyと非常によく似ています。Mingクエリ言語を使用すると、SQLAlchemyベースのTurboGearsプロジェクトをMingに移植できます。

PyMongoとは

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

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

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

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

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

D:\mongo folderMongoDBデータベースを格納するように指定されています。サーバーはでリッスンを開始します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 −これは databaseアクセスが設定されます。あなたのコレクションはimported into this module。たとえば、このパッケージに学生コレクションを追加します。

  • session.py −このファイルは session of your database connection。宣言する必要があるたびにこれをインポートする必要がありますMappedClass セッションを指定するには perform queries

  • auth.py −このファイルは、お持ちの場合に作成されます enabled authentication and authorizationクイックスタートで。3つのコレクションを定義しますrepoze.who、さらに依存するのは、ユーザー、グループ、および権限です。

コレクションの定義

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

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

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

  • FieldProperty
  • ForeignIdProperty
  • RelationProperty

ザ・ ming.schema module 次のデータ型を定義します-

  • 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

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

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)

コレクションの作成は、MongoDBWebインターフェイスおよび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()関数を呼び出します。フォームデータを取得してstudentテーブルに保存し、アプリケーションを「/ listrec」URLにリダイレクトします。これにより、studentlistテンプレートが公開されます。

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

Hello / 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")

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

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

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

サーバーを再起動して、 http://localhost:8080/add ブラウザで-

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

Gearboxツールキットにはscaffoldコマンドが含まれています。これは、TurboGearsアプリケーションの新しいコンポーネントをすばやく作成するのに非常に便利です。ギアボックスのクイックスタートコマンドによって生成されたアプリケーションには、モデルフォルダー(model.py.template)、テンプレートフォルダー(template.html.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

このコマンドは、MymodelControllerクラスが適切に定義されているcontrollers \ mymodel.pyになります。

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

テンプレートスキャフォールドtemplates \ mymodel.htmlもtemplatesフォルダーに作成されます。'/ mymodel'URLのインデックスページとして機能します。

生成された mymodel.html file テンプレートフォルダ内は次のようになります-

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

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

  • Hook −これは、イベントを定義し、イベントが発生したときに登録済みのリスナーに通知することができるメカニズムです。

  • Controller Wrapper− TurboGearsとControllerの間に位置するため、デコレータのようにコントローラを拡張できます。したがって、サードパーティのコントローラアプリケーションに接続できます。

  • Application Wrapper −これは他のWSGIミドルウェアと似ていますが、TurboGearsコンテキストでのみ機能します。

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

フック

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

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

シニア番号 フックと説明
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

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

フックを登録する

のために register a Hook, で関数を作成する 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フックは、ルートコントローラーのコントローラー関数に登録されます。次のコードを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拡張機能は次のように識別されます tgext.* package。Gearboxツールキットには、サンプル拡張機能を作成するためのtgextコマンドが用意されています。例-

gearbox tgext -n myextension

このコマンドの他のオプションのパラメーターは次のとおりです。

  • --author −パッケージ作成者の名前。

  • --email −パッケージ作成者の電子メール。

  • --licence−パッケージに使用されるライセンス。デフォルトはMITです。

  • --description −パッケージの説明。

  • --keywords −パッケージキーワード(デフォルト:turbogears2.extension)。

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

Run the setup.py ディレクトリ内-

Python setup.py install

ザ・ _init_.py 内部のファイル tgext/myextension フォルダに含まれる-

  • Plugme function −これは拡張のエントリポイントです。

  • SetupExtension class −拡張機能の初期化はここで行われます。

  • On_startup function −クラス内には、クラス内の__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

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

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

gearbox quickstart-pluggable plugtest

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

  • Controllers −アプリケーションがパージされると、自動的にマウントされます。

  • Models −プラグされたアプリケーションの内外で利用可能になります。

  • Helpers −アプリケーションテンプレートの「H」オブジェクトで自動的に公開できます。

  • Bootstrap −setup-appが呼び出されたときに実行されます。

  • Statics −これは独自のプライベートパスで利用できます。

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

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

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

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)

次の行をに組み込んで、このStudentControllerをアプリケーションのRootControllerにマウントします。 root.py

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)

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

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

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

mod_wsgiを使用したApache

mod_wsgiは、GrahamDumpletonによって開発されたApacheモジュールです。これにより、ApacheWebサーバーを使用して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の下のTurboGears

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

TurboGears-GoogleAppEngine

次のURLからPython用のGoogleAppEngineSDKをインストールします- https://cloud.google.coms

システムにGoogleAppEngineをインストールします。次に、Google Developer Consoleを開き、Googleアカウントでサインインします-https://console.developers.google.com/start

と呼ばれる新しいプロジェクトを作成します mytgapp

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

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

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

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

libraries:
   - name: webapp2
   version: "2.5.2"

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

次の内容をに追加します 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/ オンラインでアプリケーションを表示するには、にアクセスしてください。