You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cloud Run托管的Django后台上传超32MB文件?

问题描述

需要通过Django管理面板将约800MB的ZIP文件上传至GCP Cloud Storage存储桶,Django API部署在Cloud Run上,但Cloud Run存在32MB的请求大小限制,求可行解决办法。

已尝试方案

尝试过使用签名URL(Signed URLs)并将文件分割为30MB的块,但仍收到“413: Request too large”错误。从管理面板上传文件时,仍会发送包含整个文件的请求而非分块上传。以下是本地通过Cloud SQL代理可正常运行的代码:

utils.py

from django.conf import settings
from google.cloud import storage

def generate_signed_url(file_name, chunk_number):
    storage_client = storage.Client(credentials=settings.GS_CREDENTIALS)
    bucket = storage_client.bucket(settings.GS_BUCKET_NAME)
    blob_name = f'zip_files/{file_name}_chunk_{chunk_number}'
    blob = bucket.blob(blob_name)

    url = blob.generate_signed_url(
        version="v4",
        expiration=3600,
        method="PUT"
    )

    return url

def combine_chunks(bucket_name, blob_name, chunk_count):
    storage_client = storage.Client(credentials=settings.GS_CREDENTIALS)
    bucket = storage_client.bucket(bucket_name)

    # Create a list of the blobs (chunks) to be composed
    blobs = [bucket.blob(f'zip_files/{blob_name}_chunk_{i}') for i in range(chunk_count)]

    # Create a new blob to hold the composed object
    composed_blob = bucket.blob(f'zip_files/{blob_name}')

    # Compose the chunks into a single object
    composed_blob.compose(blobs)

    # Delete the chunks
    for blob in blobs:
        blob.delete()

forms.py

from django import forms
from django.conf import settings
from .models import Photoset
from .utils import generate_signed_url, combine_chunks
import requests

class PhotosetAdminForm(forms.ModelForm):
    class Meta:
        model = Photoset
        fields = ['name', 'price', "store_photo", "left_photo", "central_photo", "right_photo", "video_length", "photo_count", 'zip_file']

    def save(self, commit=True):
        instance = super().save(commit=False)

        file = self.cleaned_data.get('zip_file')
        if file:
            # Split the file into chunks
            chunk_size = 1024 * 1024 * 30  # 30MB
            chunks = [file.read(chunk_size) for _ in range(0, len(file), chunk_size)]

            # Upload each chunk separately
            for i, chunk in enumerate(chunks):
                signed_url = generate_signed_url(file.name, i)
                headers = {'Content-Type': file.content_type}
                response = requests.put(signed_url, data=chunk, headers=headers)
                if response.status_code != 200:
                    raise ValueError('A chunk could not be uploaded.')
                
            # Combine the chunks into a single file
            combine_chunks(settings.GS_BUCKET_NAME, file.name, len(chunks))

        if commit:
            instance.save()

        return instance

admin.py

...
@admin.register(Photoset)
class PhotosetAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'price', 'insert_date', 'last_modified_date')
    list_display_links = ('name',)
    list_filter = ('models',)
    search_fields = ('name', 'price')
    list_per_page = 25
    form = PhotosetAdminForm
...

zip_file是Photoset模型中的FileField字段。

内容的提问来源于stack exchange,提问作者Nicholas Kemp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:43:13