使用Django将zip文件上传到Google App Engine

时间:2014-10-31 20:42:54

标签: django google-app-engine python-2.7

简而言之,我们正尝试使用Django从Google实施以下示例:

from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers

class MainHandler(webapp2.RequestHandler):
  def get(self):
    upload_url = blobstore.create_upload_url('/upload')
    self.response.out.write('<html><body>')
    self.response.out.write('<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url)
    self.response.out.write("""Upload File: <input type="file" name="file"><br> <input type="submit"
        name="submit" value="Submit"> </form></body></html>""")

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    upload_files = self.get_uploads('file')  # 'file' is file upload field in the form
    blob_info = upload_files[0]
    self.redirect('/serve/%s' % blob_info.key())

我们的应用程序是用Django 1.x编写的。我们使用urls.py,views.py和models.py分别定义我们的url方案,视图和数据模型。

在我们的数据库中,我们需要跟踪数据文件(或至少是对磁盘上文件存在位置的引用)。目前,我们的数据模型如下:

class FileData(models.Model):
    token                   = models.CharField(max_length=10)
    file                    = models.FileField(upload_to=get_upload_file_name, null=True, default=None, blank=True)

字段&#39;令牌&#39;包含客户端应用程序将用于请求下载文件的令牌。字段&#39;文件&#39;旨在包含数据。但是,如果我们需要将其作为blob位置的引用,那么它就不会成为问题。我们现在还不知道该怎么做。什么是正确的解决方案?

我们的网址格式如下:

urlpatterns = patterns('',
    url(r'^upload/', 'views.upload', name='upload'),
    url(r'^/serve/([^/]+)?', 'views.servehandler', name='servehandler'),
)

我们的表格如下。

class DataUploadForm(forms.Form):
    """
    FileData form
    """
    token = forms.CharField(max_length=10)
    file = forms.FileField()

    class Meta:
        model = FileData
        fields = ['token', 'file', ]


    def __init__(self, *args, **kwargs):
        super(DataUploadForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            'token',
            'file',
            ButtonHolder(
                Submit('submit', 'Submit', css_class='btn btn-success btn-block'),
            ),

        )

我们的观点如下。

def upload(request):
    args = {}
    args.update(csrf(request))
    if request.method == 'POST':
        print "In /upload"
        form = DataUploadForm(request.POST, request.FILES)
        if form.is_valid():
            file_data = FileData()
            file_data.token = request.POST.get('token')
            file_data.file = request.FILES.get('file')
            print "===========> Uploading:" + file_data.token
            file_data.save()
            return render(request, 'upload_success.html', args)

    form = DataUploadForm()
    args['form'] = form
    return render(request, 'upload.html', args)

当我们执行时,我们得到:

Exception Value:    
[Errno 30] Read-only file system: u

我们做错了什么?我们如何改进我们的代码?我们如何让Google App Engine保存我们的文件,可能是在blobstore中,并提供文件存在位置的参考,以便以后下载?

请完成。描述urls.py,models.Model,views.py和yaml文件所需的更改(如有必要)。解决如何上传大文件(即每个文件大于40 MB)的问题。

请不要再向我们发送任何链接。我们搜索并看过很多帖子 - 没有一个回答这个问题。如果可以,请发布回答问题的代码片段 - 而不是链接。

1 个答案:

答案 0 :(得分:1)

您遇到此Read-only file system错误的原因是默认models.FileField将上传的文件保存到MEDIA_ROOT文件夹,并且对于Google Appengine应用程序是只读的。

您必须使用第三方FileField将上传的文件保存到Google云端存储或Amazon S3等服务。

我做了一个快速搜索,发现:

对于上传文件大小限制问题,Google Appengine的请求大小限制为32M。要支持更大的文件,您必须让用户将其文件直接上传到BlobStore或Google Cloud Storage,并构建一个回调处理程序,以将上传的文件与您的模型相关联。

检查以下链接: