先日、App Engine で提供されている Blobstore を、webapp フレームワークで使っていました。
でも、実際のアプリ開発では Kay Framework を使っているわけで。
その Kay Framework ですけど、ちゃんと Blobstore を使うためのハンドラを提供しています。試しに、先日のコードを Kay で書き変えてみました。
core/views.py
# -*- coding: utf-8 -*- import logging import urllib from google.appengine.api import users from google.appengine.api import memcache from google.appengine.ext import blobstore import werkzeug from werkzeug import exceptions from kay import utils from kay.handlers import blobstore_handlers def index(request): # アップロード用の URL を作成 # アップロードに成功したら core/upload エンドポイントへ移動させる upload_url = blobstore.create_upload_url(utils.url_for('core/upload')) # Blobstore に保存されているファイルをすべて取得 files = blobstore.BlobInfo.all() # テンプレートを使って表示 data = dict( upload_url=upload_url, files=files) return utils.render_to_response('core/index.html', data) class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): def post(self): # アップロードされたファイルの情報を取得 files = self.get_uploads('file') blob_info = files[0] # redirect メソッドが上手く動かないので、ステータスコードとヘッダを使って # ブラウザにリダイレクトを指示 headers = dict(Location=utils.url_for('core/serve', blob_key=blob_info.key())) return werkzeug.Response(None, headers=headers, status=302) class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler): def get(self, blob_key): blob_key = str(urllib.unquote(blob_key)) blob_info = blobstore.BlobInfo.get(blob_key) return self.send_blob(blob_info)
core/urls.py
# -*- coding: utf-8 -*- # core.urls # from kay.routing import ( ViewGroup, Rule ) view_groups = [ ViewGroup( Rule('/', endpoint='index', view='core.views.index'), Rule('/upload', endpoint='upload', view=('core.views.UploadHandler', (), {})), Rule('/serve/<blob_key>', endpoint='serve', view=('core.views.ServeHandler', (), {})), ) ]
core/templates/index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Top Page - core</title> </head> <body> <form action="{{ upload_url }}" method="POST" enctype="multipart/form-data"> Upload File:<input type="file" name="file"><br> <input type="submit" name="submit" value="Submit"> </form> <h2>Uploaded Files</h2> <ul> {% for file in files %} <li><a href="{{ url_for('core/serve', blob_key=file.key) }}">{{ file.filename }}</a></li> {% endfor %} </ul> </body> </html>
Kay が提供している BlobstoreUploadHandler と BlobstoreDownloadHandler は、App Engine SDK が提供している同名のクラスを移植したものなので、使い方はほとんど同じです。
注意点を挙げるなら、redirect メソッドをを使わず、ステータスコードを指定したレスポンスを返すことで、リダイレクトしているところ。redirect メソッドはボディが書き込まれたレスポンスを返しますが、App Engine のアップロード用ハンドラでリダイレクトするときは、ボディが空じゃなきゃダメみたいです。