jQuery と JSON を使う

画面が素っ気ないので jQuery でも使います。

jQuery のサイトからダウンロードしてきます。

私がダウンロードしたのは↓
http://code.jquery.com/jquery-1.7.js

ついでに jQuery UI もダウンロード。
http://jqueryui.com/

static ディレクトリに JavaScriptCSS を展開します。

crm
    static
        css
            smoothness
                images
                    *.png
                jquery-ui-1.8.16.custom.css
        js
            jquery-1.7.min.js
            jquery-ui-1.8.16.custom.min.js

Tornado で static ファイルを参照できるようにするために、下記の設定を追加。sys.argv[0] ではなく __file__ を使う方が良いと思うのですが、IDEL で実行すると __file__ は無いとエラーになるので。

static_path = os.path.join(os.path.dirname(sys.argv[0]), "static")

application = Application([
    (r"/", ViewHandler),
    (r"/view/(.*)", ViewHandler),
    (r"/static/(.*)", StaticFileHandler, {"path": static_path}),
    (r"/person/([crud])", PersonHandler),
    (r"/company/([crud])", CompanyHandler),
])

HTML の記述は下記のように。HTML はテンプレートなので、Tornado の機能として static_url 関数を使うこともできます。今回は、純粋な HTML に可能な限り近づけてみるということで、static_url 関数は使わないことにしました。

<link type="text/css" href="/static/css/smoothness/jquery-ui-1.8.16.custom.css" rel="stylesheet">
<script type="text/javascript" src="/static/js/jquery-1.7.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-ui-1.8.16.custom.min.js"></script>

なお、ViewHandler は下記のようにして、/view/person にアクセスすると person.html が返されるようにしています。

class ViewHandler(RequestHandler):
    def get(self, view_name="main"):
        self.render(view_name + ".html")

person.html では、jQuery を使って非同期通信によるデータの GET/POST を行うようにしています。例えば、こんな感じ。

  function loadItems() {
    $.get(
      "/person/r",
      null,
      function(data, status) {
        ...(略)...
        for (var i in data) {
          ...(略)...
          item.children(".id").append(data[i].id);
          item.children(".name").append(data[i].name);
          item.appendTo("#item_list");
        }
        ...(略)...
      },
      "json"
    );
  }

データは JSON 形式で受け取るようにしてます。Python では、下記のようにして JSON 形式のデータを渡しています。

    def read(self):
        session = Session()
        person_list = json.dumps(
            session.query(Person).order_by(Person.id),
            default=tr_dw2uw.person_list)
        session.close()
        return person_list

なお、tr_dw2uw.person_list は変換関数です。

def person_list(persons):
    return [{'id': p.id, 'name': p.name} for p in persons]

UI は色々と工夫が必要だなと思うところですが、ここは誰か教えてくれないかなぁ。とか思ったりします。