【问题标题】:Upload zip files to Google App Engine using Django使用 Django 将 zip 文件上传到 Google App Engine
【发布时间】:2014-12-28 06:30:23
【问题描述】:

简而言之,我们正在尝试使用 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)

“token”字段包含客户端应用程序用于请求下载文件的令牌。字段“文件”旨在包含数据。但是,如果我们需要将其作为对 blob 位置的引用,则不会有问题。我们只是不知道此时该做什么。什么是正确的解决方案?

我们的 urls 模式如下:

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)。

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

【问题讨论】:

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


【解决方案1】:

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

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

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

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

检查这些链接:

【讨论】:

  • 请注意,我引用了您提供的链接中的代码。我们正在询问如何使用 python/django 设置而不是 webapp2.RequestHandler 来做同样的事情。请注意此处问题的第一段:“简而言之,我们正在尝试使用 Django 实现来自 Google 的以下示例。”请不要再发送任何链接。我们已经搜索并看到了所有这些。如果可以的话,请发布一个示例代码来回答这个问题——而不是链接。
  • 我认为我的回答很直接。任何具有良好 Python/Django 技能的人都应该能够自己完成它。对于第一部分,只需替换您的 FileField。对于第二部分,只需编写一个像示例代码一样呈现表单的视图,然后编写另一个视图作为回调处理程序。我可以而且我以前做过。但是我只是不想写出来,因为我来SO是为了好玩回答问题而不是免费写别人的代码。
  • 我们问题的主体包含我们编写的视图“上传”。你能解决它——而不是屈尊俯就吗?
  • 天哪!你真是太侮辱人了。我们的整个网站都使用 django-crispy 表单。当我发布问题时,我复制了我们网站上存在的代码。如果表格让您感到困惑,请忘记它。重要的是我们提交了一个表单——当表单被提交时,它调用了“上传”视图。现在,您对这个问题有什么建设性的答案吗?
  • 如果您发现我的回答具有侮辱性,我很抱歉。我只是为您指出正确的方向,并希望您自己能找到真正的问题。请仔细阅读MainHandler。它呈现一个表单,但action 属性等于blobstore.create_upload_url('/upload') 的结果,您会发现该值仅指向Google 的服务器而不是您的应用程序。如果您再次检查 HTML SPEC,您会发现这意味着当表单提交时,请求将发送到 Google 的服务器。然后再次查看您的代码,它会呈现一个表单并指向您的应用程序。所以你找到了问题。
猜你喜欢
  • 1970-01-01
  • 2020-04-04
  • 2014-11-22
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
相关资源
最近更新 更多