Kay-frameworkのテンプレートの読み込み問題

Kayでのテンプレート継承 – Blog@uchikoshi22」より。

「kay/templates/」に同名のファイルがあると「myapp/templates/」よりも優先して読み込まれてしまう問題。

たとえば次のテンプレートでは「myapp/templates/base.html」ではなく「kay/templates/base.html」が読み込まれてしまう。

myapp/templates/index.html

{% extends "base.html" %}
{% block hoge %} EXTENDED? {% endblock %}

この問題はなかなか気がつかないだろう。

回避策だが、「Kayでのテンプレート継承 – Blog@uchikoshi22」にあるようにsettings.pyのTEMPLATE_DIRSで指定する。

TEMPLATE_DIRS = (
  'myapp/templates',
)

あるいは、テンプレートの方で「myapp/base.html」と指定しても良さそうだ。

myapp/templates/index.html

{% extends "myapp/base.html" %}
{% block hoge %} EXTENDED? {% endblock %}

ドキュメントの「7.4. テンプレートの読み込み」では「なお APP_DIR/templates ディレクトリは自動的に読み込みの対象になります。」とあるので、てっきり「myapp/templates/」が優先的に読み込まれると思っていたけれど、そうではないらしい。

最新のKay-fwのソースコードを追いかけていないので、何とも言えないが、自分もはまりそうで気になる。

ぜひともMLに投げていただきたいと思う。

Google App Engineでエンティティをデータストアから削除する方法

モデルインスタンスのdelete()メソッドを使うと、対応するエンティティをデータストアから削除できます。

from google.appengine.ext import db
entity = db.get(key) #モデルインスタンスを取得
entity.delete() #モデルインスタンスを削除

まとめて削除するときはdb.delete()を使用します。
db.delete()は引数に、モデルインスタンスやキー、モデルインスタンスやキーのリスト(またはiterable)を受け取ります。
モデルインスタンスのdelete()メソッドを1件ずつ使うよりも高速です。

from google.appengine.ext import db
q = MyModel.all(keys_only=True) #keys_onlty=trueをつけるとちょっと早い
results = q.fetch(10)
db.delete(results)

Google App Engine用フレームワークKayでパフォーマンス測定ツール「Appstats」を使用する

Google App Engineに用意されているパフォーマンス測定ツール「Appstats」をKayで使用する方法を紹介します。

app.yamlとsettings.pyを編集し、「Appstats」を有効にします。

app.yaml

handlers:
…
# 追加。普段のハンドラの上に書くこと
- url: /stats.*
  script: $PYTHON_LIB/google/appengine/ext/appstats/ui.py

- url: /.*
  script: kay/main.py

settings.py

MIDDLEWARE_CLASSES = (
  'google.appengine.ext.appstats.recording.AppStatsDjangoMiddleware', #追加
  'kay.auth.middleware.AuthenticationMiddleware', #追加
  …
)

以上の設定で使用できるようになりました。簡単でしたね。

開発環境で動作を確認するには「http://localhost:8080/stats」にアクセスします。

もう少し、使いやすくしましょう。

Administration Console Custom Pagesの機能を使い、Adminコンソールに追加します。

app.yaml

# 追加
admin_console:
  pages:
  - url: /stats
    name: "Stats"

参考にしたページ

Google App Engineのアンチパターン(3) Greedy module loading(貪欲なモジュール読み込み)

Google App Engine Anti Patterns by Takashi Matsuo on Prezi」より。
なお、この資料はとても参考になるので、一度目を通しておくといいと思います。

Google App Engineのアンチパターン(3) Greedy module loading(貪欲なモジュール読み込み)

「一部でしか使わないモジュールは遅延ロードする」

from kay.utils import render_to_response

import hoge_utils
import fuga_utils

def index(request):
  return render_to_response('myapp/index.html', {'message': 'Hello'})

def hoge(request):
  entries = hoge_utils.get_entries()
  return render_to_response('myapp/hoge.html', {'entries': entries})

def fuga(request):
  entries = fuga_utils.get_entries()
  return render_to_response('myapp/hoge.html', {'entries': entries})

hoge_utils、fuga_utilsはそれぞれ関数hoge()、fuga()の中でしか使用されていません。
使用しないモジュールを読み込むという、不要な処理が行われています。

修正例

from kay.utils import render_to_response

def index(request):
  return render_to_response('myapp/index.html', {'message': 'Hello'})

def hoge(request):
  import hoge_utils
  entries = hoge_utils.get_entries()
  return render_to_response('myapp/hoge.html', {'entries': entries})

def fuga(request):
  import fuga_utils
  entries = fuga_utils.get_entries()
  return render_to_response('myapp/hoge.html', {'entries': entries})

一部でしか使わないモジュールは使用されるときに読み込むようにします。
こうすることで、使用されないモジュールを読み込むことがなくなりました。

アプリケーションが大きくなるにつれて、この差が大きくなっていくように思います。