使用webapp和Django表单将文件上传到App Engine
我基本的问题是:在使用 Google App Engine 的 webapp
框架处理文件上传时,有没有类似于
form = MyForm(request.POST, request.FILES)
的东西?
我知道我可以通过 self.request.get('field_name')
或者使用 self.request.params['field_name']
的 FieldStorage 对象来提取特定上传文件的数据,但在我的情况下,我事先并不知道字段名称。我希望让表单对象来处理从请求中提取所需的数据(尤其是因为表单和随之而来的字段名称都有前缀)。
我正在将一个通用的内容管理系统从 Django(已经在 App Engine 上运行)迁移到 Google 的 webapp 框架,而这也是最后一个主要的障碍。当创建一个新项目时,我希望能够直接将 POST 的参数和文件传递给该项目的 Django 表单对象,这样我就不需要提前知道表单中有哪些字段,以及哪些字段是文件上传。这在 Django 中是可以做到的,但我在 webapp 框架中找不到简单的方法来实现。
3 个回答
self.request.arguments()
里包含了所有你可以用 self.request.get('field_name')
单独获取的元素,前提是你知道 'field_name' 的名字。
因为你事先不知道字段的名字,所以你可能想要遍历它里面的所有元素。如果你的字段名字有固定的前缀,比如 photo_cat
和 photo_dog
,这样做就没问题了。
你可以看看这个链接:app-engine-patch。使用request.FILES
的话,应该是可以正常工作的。
这里还有一段小代码片段,在这里,不过我还没有测试过:
if request.method == 'POST':
form = MyImageUploadForm( request.POST, request.FILES)
if form.is_valid():
themodel = MyImageModel()
themodel.data = form.cleaned_data['file'].read()
themodel.content_type = form.cleaned_data['file'].content_type
themodel.put()
else:
form = MyImageUploadForm()
这是我想到的解决方案。我在我自定义的 webapp.RequestHandler
子类中添加了以下方法:
# Required imports
import cgi
from django.core.files.uploadedfile import SimpleUploadedFile
def get_uploaded_files(self):
"""Gets a dictionary mapping field names to SimpleUploadedFile objects
for each uploaded file in the given params. Suitable for passing to a
Django form as the `files` argument."""
return dict((k, SimpleUploadedFile(v.filename, v.file.read()))
for k, v in self.request.params.items()
if isinstance(v, cgi.FieldStorage) and v.file)
现在,在处理上传的文件时,我可以像下面这样做:
form = MyForm(self.request.params, self.get_uploaded_files())
到目前为止,这对我来说效果很好。
(我不知道自己回答自己的问题是否合适。如果不合适,我很抱歉。)