如何在Django中从Cloud Run下载大文件

3

我有一个在Cloud Run上的Django项目。当我从以下代码所在的页面下载小文件时。

def download_view(request,pk):
    file_path = f'media/{pk}.mp3'
    name = f'{pk}.mp3'
    with open(file_path, 'rb') as f:
        response = HttpResponse(f.read(), content_type='audio/wav')
    response['Content-Disposition'] = f'attachment; filename={name}'
    return response

这个功能正常运行。然而,当我下载一个大小为50MB的文件时,我遇到了这张图片所显示的错误。 enter image description here

Cloud run的日志如下。我找不到任何回溯日志。

2021-05-06 12:00:35.668 JSTGET500606 B66 msChrome 72 https://***/download/mp3/2500762/
2021-05-06 11:49:49.037 JSTGET500606 B61 msChrome 72 https://***/download/mp3/2500645/

我不确定。这个错误是否与下载错误有关。
2021-05-06 16:48:32.570 JSTResponse size was too large. Please consider reducing response size.

我认为这是上传文件大小错误,与下载错误的主题无关。

当我在本地运行Django时,下载相同的50MB文件。我可以下载它。我认为这个下载错误与Cloud Run有关。请求/响应后停止了。所以我认为这个错误是由Cloud Run引起的,当我仍在下载文件时它已经停止了。

我不知道如何解决这个下载错误。如果您有任何解决方案,请帮助我!

2个回答

3
云运行的HTTP请求/响应大小限制为32Mb。使用multipart/form-data发送大文件的块而不是整个文件。

2
谢谢@guillaume blaquiere!我解决了下载错误。我为其他人发布我的代码。
def _file_iterator(file, chunk_size=512):
    with open(file, 'rb') as f:
        while True:
            c = f.read(chunk_size)
            if c:
                yield c
            else:
                break

def download_view(request,pk):
    file_path = f'media/{pk}.mp3'
    file_name = f'{pk}.mp3'
    response = StreamingHttpResponse(_file_iterator(file_path))
    response['Content-Type'] = 'audio/mpeg'
    response['Content-Disposition'] = f'attachment;filename="{file_name}"'
    return response

我认为 StreamingHttpResponse 是这个问题的关键点。它通过分块返回大文件,不会超过 Cloud Run 的限制。
当我使用 Content-Type 为 multipart/form-data 时,我可以下载文件。但是在智能手机上无法打开,因为它无法选择应用程序。当我在电脑上下载时,它不能显示音频文件图标。我们应该选择确切的内容类型。

enter image description here


你可以尝试设置"transfer-encoding: chunked"。 - wlhee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接