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

Django中用Celery生成缩放图片遇JSON序列化错误求助

Fixing 'InMemoryUploadedFile' is not JSON serializable Error in Celery Image Processing Task

Hey there, let's sort out this error you're hitting. You nailed the root cause already—passing the full InMemoryUploadedFile object from your form to the Celery task won't work because Celery relies on JSON serialization for task arguments, and that file object can't be converted to JSON.

Here's how to fix it step by step:

1. Pass the Saved File's Path Instead of the Form File Object

Since you're already saving the CompanyLogo instance to the database, you can use the relative path of the saved logo file (which is a plain string, fully JSON-serializable) instead of the temporary form upload object. Update your save_model method like this:

def save_model(self, request, obj, form, change):
    updated = change
    super().save_model(request, obj, form, change)
    if not updated:
        logo = CompanyLogo(logo=form.cleaned_data['logo'], company=obj)
        logo.save()
        # Use the saved logo's relative path (not the form's file object)
        task_company_logo.delay(logo.logo.name)

2. Verify Your Crop Function Works with the Path

Your existing crop_image function already joins settings.MEDIA_ROOT with the input path, which pairs perfectly with logo.logo.name (this gives the relative path under your media directory). If you haven't already, replace the placeholder image.show() with your actual resizing logic:

def crop_image(path):
    image_path = os.path.join(settings.MEDIA_ROOT, path)
    image = Image.open(image_path)
    
    # Example: Generate multiple scaled copies
    # Small size (200x200)
    small_size = (200, 200)
    small_image = image.resize(small_size)
    small_path = f"{os.path.splitext(path)[0]}_small{os.path.splitext(path)[1]}"
    small_image.save(os.path.join(settings.MEDIA_ROOT, small_path))
    
    # Medium size (400x400)
    medium_size = (400, 400)
    medium_image = image.resize(medium_size)
    medium_path = f"{os.path.splitext(path)[0]}_medium{os.path.splitext(path)[1]}"
    medium_image.save(os.path.join(settings.MEDIA_ROOT, medium_path))

Quick Notes to Keep in Mind

  • When you call logo.save(), Django automatically writes the uploaded file to your MEDIA_ROOT directory, so the path will exist when the Celery task runs.
  • If you're using a cloud storage backend (like AWS S3) instead of local files, adjust the logic to fetch the file via its storage key (still a serializable string) rather than a local filesystem path.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:44:48