在Appengine上使用Django上传JQuery文件

时间:2012-04-18 02:44:49

标签: jquery python django google-app-engine

我正在使用此plugin使用jquery上传多个文件,此项目适用于Django,但现在我正在尝试使用App Engine数据存储区。

我成功部署了,直到我尝试上传时才有效,在服务器日志中显示错误消息:

  

ValueError:App Engine存储后端仅支持BlobstoreFile   实例或文件属性为BlobstoreFile的文件实例。

我认为错误是因为在models.py中它使用了django的模型类,models.FileField,但AppEngine需要db.BlobProperty()

以下是项目链接:https://github.com/sigurdga/django-jquery-file-upload

这是我的models.py文件:

from django.db import models

class Picture(models.Model):

    # This is a small demo using FileField instead of ImageField, not
    # depending on PIL. You will probably want ImageField in your app.
    file = models.FileField(upload_to="pictures")
    slug = models.SlugField(max_length=50, blank=True)

    def __unicode__(self):
        return self.file

    @models.permalink
    def get_absolute_url(self):
        return ('upload-new', )

    def save(self, *args, **kwargs):
        self.slug = self.file.name
        super(Picture, self).save(*args, **kwargs)

有什么想法解决它吗?感谢。

1 个答案:

答案 0 :(得分:3)

好的,这里有很多值得注意的事情,它们正是App Engine工作原理的核心。

Django的Model层仅用于处理关系数据库,如MySQL,SQLite,Postgres,Oracle等。

App Engine的数据存储区是非关系型的,因此本身不能与Django模型一起使用。但是,您可以使用Django-nonrel,它充当Django模型和非关系数据库(如数据存储区)之间的转换层。

不幸的是,它仍然不是那么简单,因为Django FileField并不完全适合AppEngine BlobProperty。有一些解决方法,但数据存储无论如何都不适合提供图像。

存储图像

Google推荐两种存储和提供文件的方式,例如图片: Blobstore Google云存储

最终,存储上传图像的最佳方法是将它们存储在其中一个或另一个中,然后在模型上记录指向图像的链接。因此,如果您将模型更改为:

class Picture(models.Model):

    file_url = models.URLField()
    slug = models.SlugField(max_length=50, blank=True)

    ...

在您的视图中,使用here描述的技术将文件上传到Blobstore,然后将upload_url保存在模型上作为file_url字段。

您可以对Google云端存储执行相同操作,但由于Blobstore实际上是App Engine的一部分(而不是其他服务中的API),因此它为您提供了各种好处,如下所述。

请注意,如上所述,这仅在您使用Django-nonrel时有效,否则您将无法将Django模型保存到数据存储区。

存储模型

使用Django-nonrel,您可以按原样将上面的模型保存在数据存储区中。然而,Django-nonrel有许多需要习惯的警告,而且可能很慢。我个人不会推荐它用于新项目,但其他人可能不同意。

或者,您可以回避Django的模型层并使用App Engine's own Model layer,它旨在与数据存储区完美匹配。它包含用于引用Blobstore中对象的特定属性类型。您的模型可能如下所示:

from google.appengine.ext.blobstore import blobstore
from google.appengine.ext import db

class Picture(db.Model):

    file = blobstore.BlobReferenceProperty()
    slug = db.StringProperty(required=False)

    ...

BlobReferenceProperty为您提供的功能远远超过存储URL,因为您可以通过此属性访问文件数据,获取有关文件的数据(大小等)或处理它。如果您对存储URL感到满意,那么还有db.LinkProperty类似于Django的models.URLField

当然,使用App Engine模型而不是Django模型会失去Django模型层的许多好处以及它与Django的紧密集成。

Google Cloud SQL

如果您想使用Django模型但又不想使用Django-nonrel,还有另一种选择。如果您愿意放弃非关系数据存储的好处,可以使用Google Cloud SQL代替。 Django原生支持Cloud SQL。但是,Google Cloud SQL目前的预览范围有限,因此您可能会发现很难获得访问权限。

如果您决定使用Cloud SQL,如果您希望公开提供,则仍应将图像存储在Blobstore或Google Cloud Storage中,如上所述。