Pylonsは、コントローラーを作るときに、pasterコマンドでコードのベースを生成します。
普通のコントローラーとRestなコントローラーと二種類作成できます。
普通のコントローラーは、routing.pyの中で、URLへのマッピングを書きますが、Restコントローラーは、resourceメソッド一発で、CRUDに必要なマッピングをすべて設定してくれます。
例えばproject用のRestコントローラーを生成してマッピングすると以下のようになります。
$ paster restcontroller project projects
routes.py
mapper.resource('project', 'projects')
マッピング
- /projects/index
- 一覧など。
- /projects
- GETの場合は、indexと同じ。POSTの場合は、新規projectを保存
- /projects/new
- 新規登録フォーム
- /projects/:id
- GETの場合idで指定されたprojectの詳細,PUTで更新、DELETEで削除
- /projects/{:id};edit idで指定されたprojectの編集フォーム
あるリソースの下に紐付くリソースも存在します。
オブジェクト指向でいうとコンポジションでしょうか。
projectの例で考えてみると、タスク(task)などがあるでしょう。
project内のtaskについて、Restコントローラーを設定するには以下のようにします。
$ paster restcontroller task tasks
routes.py
mapper.resource('task', 'tasks', parent=dict(member_name='project', collection_name='projects')
このようにすると、projectリソースの下にtaskリソースが存在するようにマッピングされます。
/projects/:id/tasks/index のように、/projects/:id 以下に、task用のURLがマッピングされます。
Pylonsはテンプレート内で、コントローラーへのリンクを貼る場合には、WebHelperを使います。
上記、projectへのリンクは、
h.url('project', id=c.project.id)
などとします。
taskのように、parentを設定している場合は、以下のようになります。
h.url('project_tasks', project_id=c.project.id) # /project/:project_id/tasks
h.url('project_task_new', id=task.id, project_id=c.project.id) # /project/:project_id/tasks/:id/new
上位のリソースに対するidは、リソース名 + _id という名前になりますね。
ここで、指定されているproject_idは、引数で受け取れます。
def index(self, format='html', project_id=None):
"""GET /tasks: All items in the collection."""
# url_for('tasks')
また、Routesがenvironに格納するwsgiorg.routing_argsからも取得できます。
project_id = request.environ['wsgiorg.routing_args'][1]['project_id']
多くの場合、モデルも同様の階層となるような関連となっているため、がんばれば自動化できるかもしれません。
|