Python 2.7 已达到支持终止期限,并将于 2026 年 1 月 31 日
弃用。弃用后,您将无法部署 Python 2.7 应用,即使您的组织之前曾使用组织政策重新启用旧版运行时的部署也是如此。现有的 Python 2.7 应用在
弃用日期之后将继续运行并接收流量。我们建议您
迁移到最新支持的 Python 版本。
webapp Blobstore 处理程序
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
webapp 包含可与 Blobstore API 配合使用的请求处理程序类。BlobstoreUploadHandler
提供的逻辑可以将通过 Blobstore 传递的上传请求解析为 BlobInfo 记录,以便进一步处理。BlobstoreDownloadHandler
可帮助您轻松传送任何路径的 Blobstore 值。
BlobstoreUploadHandler
通过应用的用户或管理员发布的文件上传,将值添加到 Blobstore。应用会发布一个网络表单,其中包含文件上传字段以及将上传内容定向到 Blobstore 的表单操作。应用通过调用函数 create_upload_url(),向其传递在用户上传文件时要调用的应用处理程序的网址,以获取表单操作网址。webapp 应用程序可以使用 BlobstoreUploadHandler
类的子类作为此网址的处理程序。
get_uploads()
方法会返回一个 BlobInfo 对象列表,每个对象对应一个请求中上传的文件。每个对象均包含上传值的 Blobstore 键,以及文件名和大小等元数据。每个上传的文件在数据存储区中也有一个包含此信息的对应实体,因此您稍后可以使用给定的 blob 键来提取 BlobInfo 对象,或者对元数据字段执行数据存储区查询。上传处理程序直接从请求数据(而不是数据存储区)中解析此信息。
默认情况下,get_uploads()
将为请求中的所有上传文件返回 BlobInfo 对象。该方法还接受 field_name
参数,以便只获取给定文件上传字段的文件。返回值始终是一个列表,可以是空列表。
将 BlobstoreUploadHandler
与 Google Cloud Storage 搭配使用
如果您将此上传处理程序与 Cloud Storage 结合使用,则需要获取并存储完整的 Cloud Storage 对象文件名,因为再次从 Cloud Storage 检索该文件时需要该文件名。
使用函数 get_file_infos
,该函数会返回与每次上传对应的 FileInfo 记录列表。FileInfo
中提供了完整的 Cloud Storage 对象名称、内容类型、创建时间和其他数据。(详情请参阅链接)
BlobstoreDownloadHandler
为了提供 Blobstore 值,该应用程序会将 X-AppEngine-BlobKey
标头设置为 Blobstore 键的值(字符串形式)。如果 App Engine 在响应中看到此标头,则会将 blob 的值作为响应的正文。使用 webapp 处理程序类 BlobstoreDownloadHandler
可轻松在响应中设置此值。
send_blob()
方法可接受 BlobKey 对象、字符串键或 BlobInfo 作为 blob_key_or_info
参数,并设置响应数据以便将 Blob 值投放给该用户。该方法接受一个可选的 content_type
参数,该参数将覆盖已存储的 blob 值的 MIME 内容类型。默认情况下,blob 与上传它的客户端所设置的内容类型、从文件名中派生的内容类型或者通用类型(如果没有其他类型的信息)信息一起传送。
send_blob()
方法接受一个 save_as
参数,该参数确定是将 blob 数据作为原始响应数据还是包含文件名的 MIME 附件发送。如果该参数是字符串,则将 blob 作为附件发送,并将字符串值用作文件名。如果 True
和 blob_key_or_info
是 BlobInfo
对象,则使用该对象中的文件名。默认情况下,blob 数据将作为响应正文发送,而不是作为 MIME 附件发送。
除了发送完整的值,Blobstore 也支持只发送值的一部分,具体由字节索引范围指定。您可以使用两种方式为 BlobstoreDownloadHandler
的 send_blob()
方法提供字节索引范围。第一种方法:将该范围指定为参数 start
和 end
。
# Send the first 1,000 bytes of the value.
self.send_blob(key, start=0, end=999)
默认情况下,BlobstoreDownloadHandler
将采用请求中的 range
标头。如果需要阻止使用原始范围标头,请将 use_range=False
参数提供给 send_blob()
:
# Send the full value of the blob and
# block the "range" header.
self.send_blob(key, use_range=False)
range
标头的值是一个标准 HTTP 字节范围。BlobstoreDownloadHandler
使用 webob.byterange 解析此标头值。
完整示例应用
在以下示例应用中,应用的主网址会加载要求用户上传文件的表单,而且上传处理程序会立即调用下载处理程序来传送数据。这是为了简化示例应用。在实际运用中,您可能不会使用主网址来请求上传数据,也不会立即传送您刚上传的 blob。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-09-04。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["很难理解","hardToUnderstand","thumb-down"],["信息或示例代码不正确","incorrectInformationOrSampleCode","thumb-down"],["没有我需要的信息/示例","missingTheInformationSamplesINeed","thumb-down"],["翻译问题","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-09-04。"],[[["\u003cp\u003e\u003ccode\u003eBlobstoreUploadHandler\u003c/code\u003e is used to manage file uploads to the Blobstore, parsing upload requests and providing \u003ccode\u003eBlobInfo\u003c/code\u003e objects containing data about each file.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eget_uploads()\u003c/code\u003e method retrieves a list of \u003ccode\u003eBlobInfo\u003c/code\u003e objects for uploaded files, offering options to filter by specific file upload fields.\u003c/p\u003e\n"],["\u003cp\u003eWhen using \u003ccode\u003eBlobstoreUploadHandler\u003c/code\u003e with Google Cloud Storage, \u003ccode\u003eget_file_infos\u003c/code\u003e should be used to get a \u003ccode\u003eFileInfo\u003c/code\u003e record, in order to obtain the full cloud storage object name.\u003c/p\u003e\n"],["\u003cp\u003e\u003ccode\u003eBlobstoreDownloadHandler\u003c/code\u003e facilitates serving Blobstore values by setting the \u003ccode\u003eX-AppEngine-BlobKey\u003c/code\u003e header, allowing you to serve blobs directly to users from a specific path.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003esend_blob()\u003c/code\u003e method in \u003ccode\u003eBlobstoreDownloadHandler\u003c/code\u003e provides options to serve blobs as raw data or as a MIME attachment with a filename, and supports sending partial blob data via byte ranges.\u003c/p\u003e\n"]]],[],null,["# webapp Blobstore Handlers\n\nwebapp includes request handler classes for working with the\n[Blobstore API](/appengine/docs/legacy/standard/python/blobstore). `BlobstoreUploadHandler`\nprovides logic for parsing the upload request passed via the Blobstore into\n[BlobInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobInfo)\nrecords for further processing. `BlobstoreDownloadHandler` makes it easy to serve\nBlobstore values from any path.\n\nBlobstoreUploadHandler\n----------------------\n\nValues are added to the Blobstore via file uploads posted by users or administrators of the app.\nThe app posts a web form with a file upload field and a form action that directs the upload to the\nBlobstore. The app gets the form action URL by calling a function\n([create_upload_url()](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.create_upload_url)),\npassing it the URL of an app handler that gets called when users upload files. A webapp\napplication can use a subclass of the `BlobstoreUploadHandler` class as the handler for\nthis URL.\n\nThe `get_uploads()` method returns a list of\n[BlobInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobInfo)\nobjects, one for each uploaded file in the request. Each object contains the Blobstore key for\nthe uploaded value, as well as metadata such as the filename and size. Each uploaded file also\nhas a corresponding entity in the datastore with this information, so you can fetch the BlobInfo\nobject later given a blob key, or perform a datastore query over the metadata fields. The upload\nhandler parses this information directly from the request data, not the datastore.\n\nBy default, `get_uploads()` returns BlobInfo objects for all uploaded files in the\nrequest. The method also accepts a `field_name` argument to get just the file (or\nfiles) for a given file upload field. The return value is always a list, possibly an empty list. \n\n class PhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):\n def post(self):\n upload = self.get_uploads()[0]\n user_photo = UserPhoto(\n user=users.get_current_user().user_id(),\n blob_key=upload.key())\n user_photo.put()\n\n self.redirect('/view_photo/%s' % upload.key())\n\n### Using `BlobstoreUploadHandler` with Google Cloud Storage\n\nIf you use this upload handler with Cloud Storage, you'll need to get and store the full\nCloud Storage object file name, since this is required to retrieve the file again from Cloud Storage.\nUse the function `get_file_infos`, which returns a list of\n[FileInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.FileInfo) records\ncorresponding to each upload. The full Cloud Storage object name, content type, creation\ntime, and other data are available in the `FileInfo`. (See the link for complete details.)\n\nBlobstoreDownloadHandler\n------------------------\n\nTo serve a Blobstore value, the application sets the `X-AppEngine-BlobKey` header to\nthe value of a Blobstore key, in string form. When App Engine sees this header in the response,\nit serves the value of the blob as the body of the response. The webapp handler class\n`BlobstoreDownloadHandler` makes it easy to set this value in the response.\n\nThe `send_blob()` method takes a\n[BlobKey](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobKey)\nobject, a string key, or a\n[BlobInfo](/appengine/docs/legacy/standard/python/refdocs/google.appengine.ext.blobstore.blobstore#google.appengine.ext.blobstore.blobstore.BlobInfo)\nas the `blob_key_or_info` argument, and sets the response data so that the blob value\nwill be served to the user. The method takes an optional `content_type` argument which\noverrides the MIME content type of the stored blob value. By default, the blob is served with the\ncontent type set by the client that uploaded it, a content type derived from the filename, or a\ngeneric type if no other type information is available.\n\nThe `send_blob()` method accepts a `save_as` argument that determines\nwhether the blob data is sent as raw response data or as a MIME attachment with a filename. If\nthe argument is a string, the blob is sent as an attachment, and the string value is used as\nthe filename. If `True` and `blob_key_or_info` is a `BlobInfo`\nobject, the filename from the object is used. By default, the blob data is sent as the body of\nthe response and not as a MIME attachment. \n\n class ViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):\n def get(self, photo_key):\n if not blobstore.get(photo_key):\n self.error(404)\n else:\n self.send_blob(photo_key)\n\nThe Blobstore supports sending just part of a value instead of the full value, described as a range of byte indexes. You can provide a byte index range to `BlobstoreDownloadHandler`'s `send_blob()` method in two ways. The first is to specify the range as the arguments `start` and `end`: \n\n```python\n # Send the first 1,000 bytes of the value.\n self.send_blob(key, start=0, end=999)\n```\n\nBy default, the `BlobstoreDownloadHandler` honors the `range` header in the request. If you wish to block use of the original range header, provide the parameter `use_range=False` to `send_blob()`: \n\n```python\n # Send the full value of the blob and\n # block the \"range\" header.\n self.send_blob(key, use_range=False)\n```\n\nThe value of the `range` header is a standard [HTTP byte range](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). `BlobstoreDownloadHandler` uses [webob.byterange](http://pythonpaste.org/webob/modules/webob.html) to parse this header value.\n\nComplete sample application\n---------------------------\n\nIn the following sample application, the application's main URL loads the form that asks the user\nfor a file to upload, and the upload handler immediately calls the download handler to serve the\ndata. This is to simplify the sample application. In practice, you would probably not use the main\nURL to request upload data, nor would you immediately serve a blob you had just uploaded. \n\n from google.appengine.api import users\n from google.appengine.ext import blobstore\n from google.appengine.ext import ndb\n from google.appengine.ext.webapp import blobstore_handlers\n import webapp2\n\n\n # This datastore model keeps track of which users uploaded which photos.\n class UserPhoto(ndb.Model):\n user = ndb.StringProperty()\n blob_key = ndb.BlobKeyProperty()\n\n\n class PhotoUploadFormHandler(webapp2.RequestHandler):\n def get(self):\n upload_url = blobstore.create_upload_url('/upload_photo')\n # To upload files to the blobstore, the request method must be \"POST\"\n # and enctype must be set to \"multipart/form-data\".\n self.response.out.write(\"\"\"\n \u003chtml\u003e\u003cbody\u003e\n \u003cform action=\"{0}\" method=\"POST\" enctype=\"multipart/form-data\"\u003e\n Upload File: \u003cinput type=\"file\" name=\"file\"\u003e\u003cbr\u003e\n \u003cinput type=\"submit\" name=\"submit\" value=\"Submit\"\u003e\n \u003c/form\u003e\n \u003c/body\u003e\u003c/html\u003e\"\"\".format(upload_url))\n\n\n class PhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):\n def post(self):\n upload = self.get_uploads()[0]\n user_photo = UserPhoto(\n user=users.get_current_user().user_id(),\n blob_key=upload.key())\n user_photo.put()\n\n self.redirect('/view_photo/%s' % upload.key())\n\n\n class ViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):\n def get(self, photo_key):\n if not blobstore.get(photo_key):\n self.error(404)\n else:\n self.send_blob(photo_key)\n\n\n app = webapp2.WSGIApplication([\n ('/', PhotoUploadFormHandler),\n ('/upload_photo', PhotoUploadHandler),\n ('/view_photo/([^/]+)?', ViewPhotoHandler),\n ], debug=True)"]]