本文介绍了在Django视图中获取Google App Engine blob信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是



我有一部分图片上传到GAE Blobstore工作。这是我做的:



$ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b Property,
related_name =photo_features

caption = models.CharField(
max_length = 100

blob_key = models.CharField(
max_length = 100

在 admin中。 py 我创建了一个包含change_form呈现的覆盖的管理条目,以允许将正确的操作插入到Blobstore上传网址:

 

$ def $ render_form (self,request,context,* args,** kwargs):
from google.appengine.ext如果kwargs.has_key(add)为导入blobstore

co ntext ['blobstore_url'] = blobstore.create_upload_url('/ admin / add-photo-feature')
else:
context ['blobstore_url'] = blobstore.create_upload_url('/ admin / update-photo
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。我发现相关的问题,但似乎并不包含解决方案。我还检查了传入视图的请求对象,但找不到与blob关键字有关的任何内容。



编辑:

Django请求对象包含一个FILES字典,它会给我一个 InMemoryUploadedFile 。我认为,我应该能够从中检索到BLOB键...



编辑2:



要清楚:上传的照片出现在Blobstore中;那部分工作。


$ b 编辑3:



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

 'BlobstoreFileUploadHandler'对象没有属性'content_type_extra'


解决方案

解决这个问题非常棘手。我找到的最好的解决方案是使用项目中的文件上传处理程序(它是关联的与Django-Nonrel,但不依赖于它)。这应该处理所需的逻辑,把blob键放到 request.FILES 中,就像在Django中所期望的那样。





我忘了django-nonrel使用补丁版本的Django,其中一个补丁是在这里添加内容类型额外字段。您可以通过继承上传处理程序来复制功能,如下所示:

  from djangoappengine import storage 
class BlobstoreFileUploadHandler(storage。 BlobstoreFileUploadHandler):
把blob关键信息添加到文件对象的Handler。
$ b $ def new_file(self,field_name,* args,** kwargs):
#我们需要重新处理POST数据以获取blobkey信息。
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中引用这个子类而不是原来的。

This is a follow up question for Django on Google App Engine: cannot upload images

I got part of the upload of images to GAE Blobstore working. Here's what I did:

In models.py I created a model 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
    )

In admin.py I created an admin entry with an override for the rendering of the change_form to allow for insert of the correct action to the Blobstore upload 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)

As I use standard Django, I want to use the Django views to process the result once GAE has updated the BlobStore in stead of BlobstoreUploadHandler. I created the following views (as per the render_change_form method) and updated urls.py:

def add_photo_feature(request):

def update_photo_feature(request):

This all works nicely but once I get into the view method I'm a bit lost. How do I get the Blob key from the request object so I can store it with PhotoFeature? I use standard Django, not Django non-rel. I found this related question but it appears not to contain a solution. I also inspected the request object which gets passed into the view but could not find anything relating to the blob key.

EDIT:

The Django request object contains a FILES dictionary which will give me an instance of InMemoryUploadedFile. I presume that somehow I should be able to retrieve the blob key from that...

EDIT 2:

Just to be clear: the uploaded photo appears in the Blobstore; that part works. It's just getting the key back from the Blobstore that's missing here.

EDIT 3:

As per Daniel's suggestion I added storage.py from the djangoappengine project which contains the suggested upload handler and added it to my SETTINGS.PY. This results in the following exception when trying to upload:

'BlobstoreFileUploadHandler' object has no attribute 'content_type_extra'
解决方案

This is really tricky to fix. The best solution I have found is to use the file upload handler from the djangoappengine project (which is associated with django-nonrel, but does not depend on it). That should handle the required logic to put the blob key into request.FILES, as you'd expect in Django.

Edit

I'd forgotten that django-nonrel uses a patched version of Django, and one of the patches is here to add the content-type-extra field. You can replicate the functionality by subclassing the upload handler as follows:

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)

and reference this subclass in your settings.py rather than the original.

这篇关于在Django视图中获取Google App Engine blob信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 23:57