使用Django将zip文件上载到Google应用程序引擎

使用Django将zip文件上载到Google应用程序引擎,django,google-app-engine,python-2.7,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

简而言之,我们正在尝试使用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())
字段“token”包含客户端应用程序将用于请求下载文件的令牌。“文件”字段旨在包含数据。但是,如果我们需要将其作为一个blob位置的引用,这不会是一个问题。我们只是不知道现在该怎么办。正确的解决方案是什么

我们的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)
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)
我们的看法如下

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中,并为我们提供文件所在位置的参考,以便以后下载时使用

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


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

出现此
只读文件系统
错误的原因是默认的
models.FileField
将上载的文件保存到
MEDIA\u ROOT
文件夹,并且对于Google Appengine应用程序是只读的

您必须使用第三方
FileField
将上传的文件保存到谷歌云存储或亚马逊S3等服务中

我快速搜索了一下,发现:

对于上传文件大小限制问题,Google Appengine对请求的大小限制为32M。为了支持更大的文件,您必须让用户将其文件直接上载到BlobStore或Google云存储,并构建回调处理程序将上载的文件与您的模型链接起来

检查以下链接:


请说明如何上传大文件(即每个文件大于40 MB)。请注意,我引用了您提供的链接中的代码。我们要问的是如何使用python/django安装程序而不是webapp2.RequestHandler完成同样的事情。请注意我们问题的第一段:“简而言之,我们正在尝试使用Django从Google实现以下示例。”请不要再发送任何链接。我们都找过了,都看过了。如果可以,请发布一个示例代码来回答这个问题,而不是链接。我认为我的答案很直截了当。任何拥有优秀Python/Django技能的人都应该能够自己完成这项任务。对于第一部分,只需替换文件字段。对于第二部分,只需编写一个视图,按照示例代码呈现表单,并编写另一个视图作为回调处理程序。我可以,我以前也做过。但我只是不想写出来,因为我来这里是为了好玩而回答问题,而不是免费写别人的代码。我们的问题的主体包含了我们写的“上传”视图。你能把它修好吗--而不是把它修好吗?天哪!你太无礼了。我们的整个网站都使用django脆饼。当我发布问题时,我复制了我们网站上的代码。如果表格让你感到困惑,那就忘了它吧。重要的是我们要提交一个表单——当表单提交时,它会调用“上传”视图。现在,你对这个问题有什么建设性的回答吗?如果你觉得我的回答有侮辱性,我很抱歉。我只是给你指出了正确的方向,希望你能自己找到真正的问题所在。只需仔细阅读
MainHandler
。它呈现一个表单,但是
action
属性等于
blobstore.create_upload_url('/upload')
的结果,您会发现该值只指向Google的服务器,而不是您的应用程序。如果您再次检查HTML规范,您会发现这意味着当表单提交时,请求将进入Google的服务器。然后再看一遍你的代码,它呈现一个表单并指向你的应用程序。所以你发现了问题所在。