使用Django将zip文件上载到Google应用程序引擎
简而言之,我们正在尝试使用Django从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
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等服务中
我快速搜索了一下,发现:
MainHandler
。它呈现一个表单,但是action
属性等于blobstore.create_upload_url('/upload')
的结果,您会发现该值只指向Google的服务器,而不是您的应用程序。如果您再次检查HTML规范,您会发现这意味着当表单提交时,请求将进入Google的服务器。然后再看一遍你的代码,它呈现一个表单并指向你的应用程序。所以你发现了问题所在。