1

这是 Google App Engine 上 Django 的后续问题:无法上传图片

我得到了将图像上传到 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 上传 url 插入正确的操作:

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. 我创建了以下视图(根据 render_change_form 方法)并更新了urls.py

def add_photo_feature(request):

def update_photo_feature(request):

这一切都很好,但是一旦我进入视图方法,我就有点迷失了。如何从请求对象中获取 Blob 键,以便将其与 PhotoFeature 一起存储?我使用标准 Django,而不是 Django non-rel。我发现了这个相关的问题,但它似乎不包含解决方案。我还检查了request传递到视图中的对象,但找不到与 blob 键相关的任何内容。

编辑:

Django 请求对象包含一个 FILES 字典,它将给我一个InMemoryUploadedFile. 我想我应该能够以某种方式从中检索 blob 密钥......

编辑2:

需要说明的是:上传的照片出现在 Blobstore 中;那部分有效。它只是从这里丢失的 Blobstore 取回密钥。

编辑 3:

根据 Daniel 的建议,我从djangoappengine项目中添加了 storage.py,该项目包含建议的上传处理程序,并将其添加到我的 SETTINGS.PY 中。这会在尝试上传时导致以下异常:

'BlobstoreFileUploadHandler' object has no attribute 'content_type_extra'
4

1 回答 1

2

这真的很难解决。我发现的最佳解决方案是使用djangoappengine项目中的文件上传处理程序(与 django-nonrel 相关联,但不依赖于它)。request.FILES正如您在 Django 中所期望的那样,这应该处理将 blob 键放入 所需的逻辑。

编辑

我忘记了 django-nonrel 使用了 Django 的补丁版本,其中一个补丁在这里添加了 content-type-extra 字段。您可以通过子类化上传处理程序来复制功能,如下所示:

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 中引用这个子类,而不是原来的。

于 2013-04-16T13:19:55.957 回答