Pylonsでメモアプリ(2)

今度はコントローラを書く。
コントローラにはRESTコントローラを使ってみました。
メモ、というまさにリソースを扱おうとしているのでRESTの方がいいかなーなんて。

paster create restcontroller note notes

すると、notes.py内にいろんなメソッドが用意されてるので中身を埋めていく。
とりあえずコントローラに用意されてる一覧と作成、削除、詳細、更新を。

  • controller/notes.py
from note.model import Note, NoteTag

class NotesController(BaseController):
    def __before__(self):
      self.session = model.sac.session_context.current
      self.session.clear()

    def index(self, format='html'):
        self.list()

    def list(self, format='html'):
        c.note = self.session.query(Note).get_by(user_id=1)
        return render('list')

    def create(self):
        note = Note()
        note.title = self.form_result['title']
        note.content = self.form_result['content']
        note.user_id = 1

        self.session.save(note)
        self.session.flush()
        redirect_to('/notes')

    def new(self, format='html'):
        return render('new')

    def update(self, id):
        note = self.session.query(Note).get_by(id=id)
        note.title = self.form_result['title']
        note.content = self.form_result['content']
                                                                     
        self.session.flush()
        redirect_to('/notes')

    def edit(self, id, format='html'):
        c.note = self.session.query(Note).get_by(id=id)
        c.form_result = {
            'title': c.note.title,
            'content': c.note.content,
        }
        return render('_form')

    def confirm_delete(self, id):
        c.note = self.session.query(Note).get_by(id=id) or abrot(404)
        return render('delete')

    def delete(self, id):
        note = self.session.query(Note).get_by(id=id) or abrot(404)
        self.session.delete(note)
        self.session.flush()
        redirect_to('/notes')

    def show(self, id, format='html'):
        c.note = self.session.query(Note).get_by(id=id)
        if not c.note:
          abort(404)
        return render('detail')

「__before__()」は各関数の前処理を行ってくれるらしいので、チュートリアルにならってセッションを初期化と呼び出しやすいようにクラスのプロパティに入れときました(プロパティって呼んでいいのか?)

テンプレートに渡すデータは全部「c」って変数に入れれば、Makoテンプレートから${c.hoge}で取得できるみたい。
SQLAlchemyでマッピングしたモデルを操作してデータを取得、取得したデータをc変数に入れて、Makoで表示!


モデル操作の部分で、where ユーザーID==1 をやる場合、get_by(user_id=1)とfilter_by(user_id=1)とselect(c.Note.user_id=1)とかいろいろやり方があったんだけど、一体どれを使えばいいんだい?とりあえずget_by()にしてみた。
でも何か響き的にfilter_by()がいいかも。
変更するモデルインスタンスをSQLAlchemyのセッションにsaveしてflushで変更、あるいは削除を実行する、という感じみたいです。


まだユーザー認証を作ってないので、create時にuser_idには1を入れてます。
タグもまだ未実装なのでこれからこれから。。。


コントローラを書いたら、URLの定義。

  • route.py
    map.resource('note', 'notes')
    map.connect('confirm_delete', 'notes/:(id);delete', controller='notes', 
        action='confirm_delete', condition=dict(method='GET'))

削除前には確認画面をはさみたいので、確認用画面をGETで表示して、そこからDELETEメソッドで削除という流れになる。
っていうかHTTPでDELETEメソッド初めて使ったよ。。。
でも確かRFCではPOSTで変更・削除しても一応オッケーなんじゃなかったっけ。
厳格にはPUTとDELETE使えって感じだったような、、後でRFCもう一回見てみよう。


と、いうわけで基本的なCRUDは動くようになったので、
次からはページャとタグクラウドの実装をしていきまっす。
ついでにCSSも書いて画面キャプチャも出していこう。