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

如何让Celery任务接收文件列表参数并解决序列化问题

解决Celery任务接收文件列表参数的序列化问题

核心问题

Celery默认使用JSON序列化任务参数,而JSON无法直接处理二进制数据(bytes)或InMemoryUploadedFile对象;非文本文件(如图片、二进制文档)也无法通过UTF-8解码为字符串,这就是你遇到各类报错的根源。以下是三种可行的解决方案:

方案1:Base64编码二进制内容(推荐用于小文件)

将文件二进制内容编码为Base64字符串(可被JSON序列化),任务执行时再解码回二进制:

上传端代码修改:

import base64

files = {}
for file in request.FILES.getlist('files'):
    file_content = file.file.read()
    # 二进制转Base64字符串
    files[file.name] = base64.b64encode(file_content).decode('utf-8')

my_celery_task.apply_async(kwargs={'files': files})

Celery任务代码:

import base64

@celery.task
def my_celery_task(files):
    processed_files = {}
    for name, content_b64 in files.items():
        # Base64字符串转回二进制
        processed_files[name] = base64.b64decode(content_b64)
    # 在这里执行你的文件处理逻辑

方案2:更换Celery序列化器为Pickle(仅适用于可信环境)

Pickle可以序列化Python对象(包括bytes和InMemoryUploadedFile),但存在安全风险——反序列化不可信数据可能导致恶意代码执行,仅在任务队列完全由内部可信任务使用时采用:

修改Celery配置:

app = Celery('your_app')
app.conf.update(
    task_serializer='pickle',
    accept_content=['pickle'],
    result_serializer='pickle',
)

上传端代码(无需编码,直接传bytes):

files = {}
for file in request.FILES.getlist('files'):
    files[file.name] = file.file.read()

my_celery_task.apply_async(kwargs={'files': files})

方案3:先存储文件,传递路径/URL(推荐用于大文件)

将上传的文件先保存到本地磁盘或云存储,然后将文件路径/URL传递给Celery任务,任务执行时读取文件内容:

上传端代码(以Django默认存储为例):

from django.core.files.storage import default_storage
from django.core.files.base import ContentFile

files = {}
for file in request.FILES.getlist('files'):
    # 保存临时文件,生成存储路径
    temp_path = default_storage.save(f'temp_uploads/{file.name}', ContentFile(file.read()))
    files[file.name] = temp_path

my_celery_task.apply_async(kwargs={'files': files})

Celery任务代码:

from django.core.files.storage import default_storage

@celery.task
def my_celery_task(files):
    processed_files = {}
    for name, file_path in files.items():
        with default_storage.open(file_path, 'rb') as f:
            processed_files[name] = f.read()
    # 执行文件处理逻辑
    # 处理完成后可删除临时文件
    for path in files.values():
        default_storage.delete(path)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:25:33