コントローラーの構築
コントロラーは、リクエストがウェブサービスに来たときにコードを取得して実行する記述の方法です。
Python関数へリクエストURLとパラメータの一致して TurboGearsはCherryPyを呼び出して利用します。
tutorial/controllers.pyを開き、追記と修正を始めます。
contorollers.pyのRoot classを下のコードで置き換えたら、TurboGearsの"Hello, world!"相当のアプリケーションができます。
class Root(controllers.RootController): @turbogears.expose() def index(self): return "Hello, world!"
もう一度サーバをスタートさせて、ブラウザでhttp://localhost:8080へアクセスします。すると、テキストの中に"Hello, world!"が表示されます。
どうですか、動いていますか?
RootコントローラーはウェブサービスのルートURL(/)に相当します。/ のリクエストを受け取ったら、TurboGearsはRoot Controllerのiindex メソッドを見ます。indexメソッドはウェブディレクトリのindex.htmlに相当します。
publicリソース(expose)を作ります。exposeはturbogears.exposeに付随のディレクターです。*1
@turbogears.expose()
コード内のexposedメソッドはリソースを受け取った時に実行されます。Rootコントローラにはたくさんのresourceを追加することができます。
@turbogears.expose() def about(self): return "This tutorial was written by Brian Beck."
ブラウザでhttp://localhost:8080/about をアクセスしてください。
開発中はWEBサーバの再起動なしにコントローラーを作り替えることが可能です。
リクエストはパラメータも持っています。GETリクエストのURLやエンコード済みのフォームinput内のPOSTリクエストがあります。
両方のメソッドはどちらもコントローラでは同じ方法です。
@turbogears.expose() def about(self, author="Brian Beck"): return "This tutorial was written by %s." % author
/aboutのリクエストではのテキストメッセージが出てきます。しかし、レスポンス /about?autor=Napoleon の表示は次のようになります。
"This tutorial was written by Napoleon."
pathコンポーネントを加えます。
resourceを含んだクラスインスタンスをRootコントローラのアトリビュートに加えます。
ここに"users"pathコンポーネントをRootコントローラへ加えます
import model class Users: @turbogears.expose() def index(self): users = model.User.select() ※ import model が必要 return ", ".join(user.email for user in users) class Root(controllers.RootController): users = Users() ...
/users/indexか/usresにブラウズするとデータベースの中のusersリストが表示されます。
コントローラーの構造はCherryPyのドキュメントを参照します。
http://www.cherrypy.org/wiki/CherryPyBook
いくつかのuserは自分自身のリソースをUsersコントローラの中に持っています。
しかし、この要求はデータベース内のすべてのユーザのメソッドに加えることとなる。
幸運にも、これらはダイナミックpathコンポーネントで簡単に解決できる。リソース要求があったとき、対応したコントローラーが見つけることができない。呼び出されたdefaultメソッドはリクエストリソースの名前を引数(argument)として呼び出されます。
class Users: ... @turbogears.expose() def default(self, userID): try: userID = int(userID) except ValueError: return "Invalid user ID!" try: user = model.User.get(userID) except model.SQLObjectNotFound: return "No such user!" else: return user.email
ブラウザで/user/1にリクエストするとID 1のユーザのe-mailアドレスが表示されるか、IDが見つからなかった場合に"No such user!"と表示されます。/users/dogをリクエストすると通常tableのIDはIntegersなので"invalid user ID!"と表示されます。
とりあえず今日はここまで。
残りは次回に続く。。。のか???
*1:from turbogears import expose を記述してると@expose()だけでよい