如何将文件上传到blobstore或通过django-filetransfer?

时间:2012-07-31 23:38:46

标签: django google-app-engine djangoappengine

目前,我们使用Google Cloud SQL在app引擎上托管的应用程序的默认Django FileField上传方法会返回以下错误:

OSError
[Errno 38] Function not implemented: '/base/data/home/apps/s~app/attachment-1.360717349796013945/media'

这可能是因为文件写入在app引擎中被限制而mkdir在Django调试模式中没有工作:

/base/python27_runtime/python27_dist/lib/python2.7/os.py in makedirs
makedirs(head, mode)
    except OSError, e:
        # be happy if someone already created the path
        if e.errno != errno.EEXIST:
            raise
    if tail == curdir:           # xxx/newdir/. exists if xxx/newdir exists
        return
mkdir(name, mode) ...

因此,我尝试安装django-filetransfer,并且相同的错误仍然存​​在于Appengine上。

Django设置:

模型

class OrderItemAttachmentForm(ModelForm):
class Meta:
    model = OrderItemAttachment
    exclude = ('item',)
def __init__(self, *args, **kwargs):
    super(OrderItemAttachmentForm, self).__init__(*args, **kwargs)

视图

def RFO(request):
    view_url = reverse('app.views.RFO')
    elif 'saveLine' in request.POST:
        order_attachment_form = OrderItemAttachmentForm(request.POST,request.FILES)
        if order_attachment_form.is_valid():
            order_attachment = order_attachment_form.save()
    upload_url, upload_data = prepare_upload(request, view_url)

模板

{% load filetransfers %}
<form id="requestItemForm" name="requestItemSubmit" method="post" enctype="multipart/form-data" action="{{ upload_url }}">{% csrf_token %}{% render_upload_data upload_data %}
<div class="lineAttach">
<label for="id_attachment">Upload Attachment</label>
{{order_attachment_form.attachment}}
</div>
<button type="submit" id="saveLine" name="saveLine" class="btn grey doLoad right" value="Save Line Item">Save Line Item</button>

我已考虑使用Blobstore python API将文件存储为blob或使用Google云端存储,但不知道如何将其集成到Django模型中。任何帮助将不胜感激,谢谢!

2 个答案:

答案 0 :(得分:1)

我遇到了同样的麻烦。我认为django-filetransfer需要djangoappengine才能正常运行。我现在采取不同的方法来解决问题。我不能使用这么方便的工具太糟糕了。

答案 1 :(得分:0)

我知道这是在之前发布的,但答案非常简单(即使它并不明显):

您的ModelForm很好,但您实际上可以删除__init__函数,因为它所做的就是将详细信息传递给无论如何都要发生的父类。

您的视图需要做一些特定的事情: prepare_upload 以获取正确的上传URL,并处理GET和POST案例(Blobstore将在文件被执行后对您的表单执行回调如果你使用基于类的视图,它可能看起来像这样:

class OrderAttachmentView(FormView):

    def get(self, request):
        upload_url, upload_data = prepare_upload(
            request,
            reverse('attachment-upload'),
            private=True,
            )
        form = OrderItemAttachmentForm()
        return render(
            request,
            'attachment_form.html',
            {
                'form': form,
                'upload_url': upload_url,
                'upload_data': upload_data,
            },
        )

    def post(self, request):
        form = OrderItemAttachmentForm(request.POST, request.FILES)
        order_item_attachment = form.save()
        return HttpResponseRedirect(reverse(
            'attachment-detail',
            kwargs={'pk': order_item_attachment.id},
            ))

您的表单需要自定义操作参数:

{% load filetransfers %}

<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
    ...
    <input type="submit" value="Upload" />
</form>