ユーザーが Visual Studio プロジェクト ファイルをダウングレードできる Web アプリを作成する予定です。db.TextPropertyただし、Google App Engine はとを介して Google サーバーにファイルのアップロードとフラット ファイルの保存を受け入れるようですdb.BlobProperty。
これを行う方法について、誰でもコード サンプル (クライアント側とサーバー側の両方) を提供できることを嬉しく思います。
ユーザーが Visual Studio プロジェクト ファイルをダウングレードできる Web アプリを作成する予定です。db.TextPropertyただし、Google App Engine はとを介して Google サーバーにファイルのアップロードとフラット ファイルの保存を受け入れるようですdb.BlobProperty。
これを行う方法について、誰でもコード サンプル (クライアント側とサーバー側の両方) を提供できることを嬉しく思います。
実際、この質問は App Egnine のドキュメントで回答されています。ユーザー画像のアップロードの例を参照してください。
<form></form> 内の HTML コード:
<input type="file" name="img"/>
Python コード:
クラス ゲストブック (webapp.RequestHandler):
デフポスト(自己):
挨拶 = 挨拶()
users.get_current_user() の場合:
greeting.author = users.get_current_user()
greeting.content = self.request.get("コンテンツ")
アバター = self.request.get("img")
greeting.avatar = db.Blob(アバター)
あいさつ.put()
self.redirect('/')
これは完全な作業ファイルです。Google サイトからオリジナルを引っ張ってきて、それを少し現実的なものにするために修正しました。
注意すべき点がいくつかあります。
ServeHandler クラスのこの行の目的は、キーを「修正」して、ブラウザーで発生した可能性のある名前のマングリングを取り除くことです (Chrome では何も観察しませんでした)。
blob_key = str(urllib.unquote(blob_key))
この最後の「save_as」句は重要です。ブラウザに送信されるときにファイル名が壊れないようにします。何が起こるかを観察するためにそれを取り除きます。
self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
幸運を!
import os
import urllib
from google.appengine.ext import blobstore
from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
class MainHandler(webapp.RequestHandler):
def get(self):
upload_url = blobstore.create_upload_url('/upload')
self.response.out.write('<html><body>')
self.response.out.write('<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url)
self.response.out.write("""Upload File: <input type="file" name="file"><br> <input type="submit" name="submit" value="Submit"> </form></body></html>""")
for b in blobstore.BlobInfo.all():
self.response.out.write('<li><a href="/serve/%s' % str(b.key()) + '">' + str(b.filename) + '</a>')
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
upload_files = self.get_uploads('file')
blob_info = upload_files[0]
self.redirect('/')
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, blob_key):
blob_key = str(urllib.unquote(blob_key))
if not blobstore.get(blob_key):
self.error(404)
else:
self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
def main():
application = webapp.WSGIApplication(
[('/', MainHandler),
('/upload', UploadHandler),
('/serve/([^/]+)?', ServeHandler),
], debug=True)
run_wsgi_app(application)
if __name__ == '__main__':
main()
今日試してみましたが、次のように機能します。
SDK のバージョンは 1.3.x です
html ページ:
<form enctype="multipart/form-data" action="/upload" method="post" >
<input type="file" name="myfile" />
<input type="submit" />
</form>
サーバーコード:
file_contents = self.request.POST.get('myfile').file.read()
Google は、大きなファイルを保存するためのサービスをリリースしました。blobstore API ドキュメントをご覧ください。ファイルが 1MB を超える場合は、それを使用する必要があります。
それでも問題が解決しない場合は、フォーム タグで enctype を使用していることを確認してください
いいえ:
<form encoding="multipart/form-data" action="/upload">
はい:
<form enctype="multipart/form-data" action="/upload">
個人的には、 GAEでJavaランタイムを使用するときに、ここで説明するチュートリアルが役立つと思いました。どういうわけか、を使ってファイルをアップロードしようとしたとき
<form action="/testservelet" method="get" enctype="multipart/form-data">
<div>
Myfile:<input type="file" name="file" size="50"/>
</div>
<div>
<input type="submit" value="Upload file">
</div>
</form>
何らかの理由でHttpServletクラスが'enctype'属性のフォームを受け入れないことがわかりました。削除しても機能しますが、これはファイルをアップロードできないことを意味します。
従来のファイル システムがないため、ファイルを保存することはできません。それらは独自の DataStore ( BlobPropertyとして定義されたフィールド)にのみ保存できます。
前のリンクに例があります。
class MyModel(db.Model):
blob = db.BlobProperty()
obj = MyModel()
obj.blob = db.Blob( file_contents )
AppEngineにファイルをアップロードするときに奇妙な動作が見られました。次のフォームを送信する場合:
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="img" />
...
</form>
img次に、次のようにリクエストからを抽出します。
img_contents = self.request.get('img')
img_contents変数はstr()GoogleChromeではaですが、FirefoxではUnicodeです。そして今のように、db.Blob()コンストラクターは文字列を受け取り、Unicode文字列を渡すとエラーをスローします。
誰かがこれを修正する方法を知っていますか?
また、私が絶対に奇妙だと思うのは、ゲストブックアプリケーション(アバター付き)をコピーして貼り付けると、完全に機能することです。私は自分のコードですべてをまったく同じように実行しますが、それは機能しません。私は髪を抜くのに非常に近いです。
フラットファイルシステムを使用する方法があります(少なくとも使用の観点から)
このGoogle App Engine Virtual FileSystem プロジェクトがあります。通常のファイルシステムをエミュレートするために、データストアおよび memcache API を使用して実装されます。このライブラリを使用すると、同様のファイルシステム アクセス (読み取りおよび書き込み)をプロジェクトで使用できます。
Google App Engine にはフラット ファイルの保存はありません。リレーショナルデータベースに少し似ていますが、完全ではありません。
ファイルをTextPropertyまたはBlobProperty属性として保存できます。
DataStore エントリには 1MB の制限があり、問題になる場合とそうでない場合があります。