在Django视图中获取Google App Engine blob信息

时间:2013-04-16 09:59:20

标签: django google-app-engine file-upload

这是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'

1 个答案:

答案 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中引用此子类,而不是原始。