关于python:在Google App Engine中上传文件

关于python:在Google App Engine中上传文件

Upload files in Google App Engine

我打算创建一个Web应用程序,允许用户降级Visual Studio项目文件。 但是,似乎Google App Engine可以通过db.TextPropertydb.BlobProperty在Google服务器上接受文件上传和平面文件存储。

我很高兴任何人都可以提供有关如何完成此工作的代码示例(客户端和服务器端)。


实际上,该问题在App Egnine文档中得到了回答。请参阅有关上传用户图像的示例。

中的HTML代码:

1
<input type="file" name="img"/>

Python代码:

1
2
3
4
5
6
7
8
9
10
class Guestbook(webapp.RequestHandler):
  def post(self):
    greeting = Greeting()
    if users.get_current_user():
      greeting.author = users.get_current_user()
    greeting.content = self.request.get("content")
    avatar = self.request.get("img")
    greeting.avatar = db.Blob(avatar)
    greeting.put()
    self.redirect('/')

这是一个完整的工作文件。我从Google网站上提取了原始图片,并对其进行了修改,使其更加真实。

注意事项:

  • 此代码使用BlobStore API
  • 此行的目的是
    ServeHandler类用于"修复"
    键,使其摆脱任何名称
    可能发生在
    浏览器(我没有在
    铬)

    1
    blob_key = str(urllib.unquote(blob_key))
  • 最后的" save_as"子句很重要。它将确保文件名在发送到浏览器时不会被篡改。摆脱它,观察会发生什么。

    1
    self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
  • 祝好运!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    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"> <input type="submit" name="submit" value="Submit"> </form></body></html>""")

            for b in blobstore.BlobInfo.all():
                self.response.out.write('
    <li>
    '
    + str(b.filename) + '')

    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()


    Google网上论坛对此有一个话题:

    上载档案

    有了很多有用的代码,该讨论对我上载文件有很大帮助。


    我今天尝试,它的工作方式如下:

    我的SDK版本是1.3.x

    html页面:

    1
    2
    3
    4
    <form enctype="multipart/form-data" action="/upload" method="post">
    <input type="file" name="myfile" />
    <input type="submit" />
    </form>

    服务器代码:

    1
    file_contents = self.request.POST.get('myfile').file.read()

    Google发布了一项用于存储大文件的服务。看看blobstore API文档。如果文件> 1MB,则应使用它。


    如果仍然有问题,请检查您是否在表单标签中使用enctype

    没有:

    1
    <form encoding="multipart/form-data" action="/upload">

    是:

    1
    <form enctype="multipart/form-data" action="/upload">


    我个人发现,此处所述的教程在将GAE与Java运行时结合使用时非常有用。由于某些原因,当我尝试使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <form action="/testservelet" method="get" enctype="multipart/form-data">
       
            Myfile:<input type="file" name="file" size="50"/>
       

       
            <input type="submit" value="Upload file">
       
    </form>

    我发现我的HttpServlet类由于某种原因不接受带有'enctype'属性的表单。删除它是可行的,但是,这意味着我无法上传任何文件。


    您无法存储文件,因为没有传统的文件系统。您只能将它们存储在自己的DataStore中(在定义为BlobProperty的字段中)

    上一个链接中有一个示例:

    1
    2
    3
    4
    5
    class MyModel(db.Model):
      blob = db.BlobProperty()

    obj = MyModel()
    obj.blob = db.Blob( file_contents )

    有一种使用平面文件系统的方法(用法方面为Atleast)

    有这个Google App Engine虚拟文件系统项目。可以借助数据存储区和内存缓存API来实现,以模拟普通文件系统。使用此库,您可以在项目中使用类似的文件系统访问(读取和写入)。


    在App Engine上上传文件时,我观察到一些奇怪的行为。当您提交以下表格时:

    1
    2
    3
    4
    <form method="post" action="/upload" enctype="multipart/form-data">
        <input type="file" name="img" />
        ...
    </form>

    然后从请求中提取img,如下所示:

    1
    img_contents = self.request.get('img')

    img_contents变量在Google Chrome中是str(),但在Firefox中是unicode。和现在一样,db.Blob()构造函数采用一个字符串,如果传入unicode字符串,则会引发错误。

    有谁知道如何解决?

    另外,我发现绝对奇怪的是,当我复制并粘贴Guestbook应用程序(带有头像)时,它可以完美运行。我在代码中完全按照相同的方式进行操作,但无法正常工作。我离拔头发很近。


    Google App Engine中没有平面文件。一切都必须进入数据存储,这有点像关系数据库,但不完全是。

    您可以将文件存储为TextProperty或BlobProperty属性。

    DataStore条目的限制为1MB,这可能会或可能不会成为问题。


    推荐阅读

      linux命令删除用户组?

      linux命令删除用户组?,管理,密码,系统,用户组,用户,概念,命令,文件,管理员,

      linux注销命令用户?

      linux注销命令用户?,系统,服务,密码,地址,工作,命令,状态,工具,信息,基础,lin

      linux命令所有用户?

      linux命令所有用户?,系统,密码,信息,情况,名称,命令,用户,时间,地址,位置,如

      linux命令进入用户?

      linux命令进入用户?,系统,密码,用户,地址,信息,软件,命令,用户名,联系方式,

      linux命令用户管理?

      linux命令用户管理?,系统,密码,管理,工作,信息,地址,工具,命令,用户,基础,LIn

      linux用户与组的命令?

      linux用户与组的命令?,管理,系统,名称,用户组,密码,用户,命令,情况,信息,单

      linux添加用户的命令?

      linux添加用户的命令?,密码,系统,软件,联系方式,用户,新增,信息,管理人员,

      linux用户退出的命令?

      linux用户退出的命令?,系统,密码,命令,用户,发行,电脑,第三,地址,软件,信息,l

      linux看系统用户命令?

      linux看系统用户命令?,系统,信息,密码,命令,服务,名称,网络,情况,软件,工具,L

      linux赋权用户命令?

      linux赋权用户命令?,系统,密码,用户,权限,地址,状态,数字,软件,管理,电脑,Lin

      linux组加用户命令?

      linux组加用户命令?,系统,密码,联系方式,用户,软件,管理,命令,用户名,用户

      linux命令中添加用户?

      linux命令中添加用户?,系统,密码,软件,用户,命令,信息,目录,用户名,账号,文

      linux命令更改用户?

      linux命令更改用户?,系统,密码,管理,用户,命令,环境,工作,地址,电脑,文件,lin

      linux修改用户名命令?

      linux修改用户名命令?,系统,密码,查询系统,代码,数字,用户名,命令,第三,电

      linux命令给用户授权?

      linux命令给用户授权?,系统,数字,管理,权限,命令,密码,工具,时间,软件,信息,l

      linux命令创建用户组?

      linux命令创建用户组?,系统,代码,密码,用户组,用户,命令,信息,名称,新增,管

      linux命令给用户授权?

      linux命令给用户授权?,系统,数字,管理,权限,命令,密码,工具,时间,软件,信息,l

      linux命令创建用户组?

      linux命令创建用户组?,系统,代码,密码,用户组,用户,命令,信息,名称,新增,管

      查看linux用户命令行?

      查看linux用户命令行?,信息,系统,时间,名称,密码,用户,命令,地址,状态,设备,L