这是Django on Google App Engine: cannot upload images
的后续问题我将部分图像上传到GAE Blobstore工作。这是我做的:
在models.py
我创建了一个模型PhotoFeature
:
class PhotoFeature(models.Model):
property = models.ForeignKey(
Property,
related_name = "photo_features"
)
caption = models.CharField(
max_length = 100
)
blob_key = models.CharField(
max_length = 100
)
在admin.py
中,我创建了一个管理员条目,其中包含了对change_form呈现的覆盖,以允许向Blobstore上传网址插入正确的操作:
class PhotoFeatureAdmin(admin.ModelAdmin):
list_display = ("property", "caption")
form = PhotoFeatureForm
def render_change_form(self, request, context, *args, **kwargs):
from google.appengine.ext import blobstore
if kwargs.has_key("add"):
context['blobstore_url'] = blobstore.create_upload_url('/admin/add-photo-feature')
else:
context['blobstore_url'] = blobstore.create_upload_url('/admin/update-photo-feature')
return super(PhotoFeatureAdmin, self).render_change_form(request, context, args, kwargs)
当我使用标准Django时,我希望在GAE更新BlobStore而不是BlobstoreUploadHandler
时使用Django视图来处理结果。我创建了以下视图(根据render_change_form方法)并更新了urls.py
:
def add_photo_feature(request):
def update_photo_feature(request):
这一切都很好用,但是一旦我进入视图方法,我就有点迷失了。如何从请求对象获取Blob键,以便我可以使用PhotoFeature存储它?我使用标准Django,而不是Django非rel。我找到了this相关问题,但似乎没有包含解决方案。我还检查了传递到视图中的request
对象,但找不到与blob键有关的任何内容。
修改
Django请求对象包含一个FILES字典,它将为我提供InMemoryUploadedFile
的实例。我认为我应该能够从那个地方检索blob密钥......
编辑2:
为了清楚起见:上传的照片出现在Blobstore中;那部分有效。它只是从这里缺少的Blobstore中获取密钥。
编辑3:
根据Daniel的建议,我在djangoappengine项目中添加了包含建议的上传处理程序的storage.py,并将其添加到我的SETTINGS.PY中。尝试上传时会出现以下异常:
'BlobstoreFileUploadHandler' object has no attribute 'content_type_extra'
答案 0 :(得分:2)
修复这个问题真的很棘手。我找到的最佳解决方案是使用djangoappengine项目中的文件上传处理程序(与django-nonrel相关联,但不依赖于它)。这应该处理将blob键放入request.FILES
所需的逻辑,正如您在Django中所期望的那样。
修改强>
我忘记了django-nonrel使用了修补版本的Django,其中一个补丁就是添加内容类型额外字段。您可以通过继承上传处理程序来复制功能,如下所示:
from djangoappengine import storage
class BlobstoreFileUploadHandler(storage.BlobstoreFileUploadHandler):
"""Handler that adds blob key info to the file object."""
def new_file(self, field_name, *args, **kwargs):
# We need to re-process the POST data to get the blobkey info.
meta = self.request.META
meta['wsgi.input'].seek(0)
fields = cgi.FieldStorage(meta['wsgi.input'], environ=meta)
if field_name in fields:
current_field = fields[field_name]
self.content_type_extra = current_field.type_options
super(BlobstoreFileUploadHandler, self).new_file(field_name,
*args, **kwargs)
并在您的settings.py中引用此子类,而不是原始。