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

为何DATA_UPLOAD_MAX_MEMORY_SIZE在Django+TinyMCE环境下不生效?

问题描述

在Django项目的settings.py中,已在非生产环境分支配置DATA_UPLOAD_MAX_MEMORY_SIZE = 209_715_200(200MB)和FILE_UPLOAD_MAX_MEMORY_SIZE = 209_715_200,但在TinyMCE文本字段中添加总大小超2.5MB的5张图片时,仍收到错误:Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE。

相关代码片段如下:

settings.py 关键配置

# ... 其他配置 ...
if os.environ.get("PRODUCTION"):
    # 生产环境邮件配置
    EMAIL_HOST = 'smtp.gmail.com'
    # ... 其余邮件配置 ...
else:
    EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
    DATA_UPLOAD_MAX_MEMORY_SIZE = 209_715_200
    FILE_UPLOAD_MAX_MEMORY_SIZE = 209_715_200

views.py 编辑文章视图

def edit_post(request, slug):
    post = get_object_or_404(Post, slug=slug)
    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            post.author = request.user.profile
            post.createdDateTime = timezone.now()
            if post.title != form.cleaned_data["title"]:
                post.slug = unique_slugify(post.title.lower())
            if "thumbnail" in request.FILES:
                post.thumbnail = request.FILES["thumbnail"]
            post.save()
            return redirect('profile-details')
    else:
        form = PostForm(instance=post)
    return render(request, 'portfolio/edit_post.html', {'form': form})

HTML模板核心片段

<form method="POST" class="post-form" enctype="multipart/form-data">
    {% csrf_token %}
    <!-- ... 表单其他字段 ... -->
    <div class="row box-text">
        {{ form.text }}
    </div>
    <!-- ... 其他内容 ... -->
</form>
解决方案

1. 确保内存限制配置全局生效

你的DATA_UPLOAD_MAX_MEMORY_SIZE和FILE_UPLOAD_MAX_MEMORY_SIZE仅在非生产环境(PRODUCTION环境变量不存在时)加载。如果服务器运行在生产环境(比如PythonAnywhere),这两个配置不会生效,Django会使用默认值(2.5MB),这正是报错的核心原因。

修改settings.py,将这两个配置移到if-else分支外,确保所有环境都能加载:

# ... 其他配置 ...
# 全局设置上传内存限制(200MB)
DATA_UPLOAD_MAX_MEMORY_SIZE = 209_715_200
FILE_UPLOAD_MAX_MEMORY_SIZE = 209_715_200

if os.environ.get("PRODUCTION"):
    # 生产环境邮件配置
    EMAIL_HOST = 'smtp.gmail.com'
    # ... 其余邮件配置 ...
else:
    EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

2. 配置TinyMCE图片直传(避免Base64嵌入)

默认情况下,TinyMCE会将插入的图片转成Base64编码嵌入到textarea内容中,这会让POST请求体体积增加33%以上。改为直接上传图片到服务器,仅在内容中保存图片URL,可彻底规避请求体大小限制:

步骤1:修改TinyMCE配置

在settings.py的TINYMCE_DEFAULT_CONFIG中添加上传相关配置:

TINYMCE_DEFAULT_CONFIG = {
    # ... 原有配置 ...
    'images_upload_url': '/upload-image/',  # 指定上传接口
    'images_upload_credentials': True,  # 携带CSRF凭证
    'images_file_types': 'jpeg,jpg,png,gif',  # 允许的图片格式
}

步骤2:编写图片上传视图

在views.py中添加处理图片上传的视图:

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import os
from django.conf import settings
from uuid import uuid4

@csrf_exempt
def upload_image(request):
    if request.method == 'POST' and request.FILES.get('file'):
        file = request.FILES['file']
        # 生成唯一文件名避免重复
        filename = f"{uuid4().hex}{os.path.splitext(file.name)[1]}"
        # 定义存储路径
        save_dir = os.path.join(settings.MEDIA_ROOT, 'tinymce_images')
        os.makedirs(save_dir, exist_ok=True)
        file_path = os.path.join(save_dir, filename)
        
        # 分片保存文件
        with open(file_path, 'wb+') as destination:
            for chunk in file.chunks():
                destination.write(chunk)
        
        # 返回图片URL给TinyMCE
        return JsonResponse({
            'location': f"{settings.MEDIA_URL}tinymce_images/{filename}"
        })
    return JsonResponse({'error': '无效请求'}, status=400)

步骤3:配置上传路由

在项目的urls.py中添加上传接口的路由:

from django.urls import path
from . import views

urlpatterns = [
    # ... 其他路由 ...
    path('upload-image/', views.upload_image, name='tinymce_upload'),
]

3. 检查服务器层面的请求大小限制

如果部署在PythonAnywhere等平台,平台本身可能有默认请求大小限制(比如2MB),需要手动调整:

  • 登录PythonAnywhere后台,进入Web选项卡,在"Max request size"处设置为200MB(209715200字节)
  • 若使用Apache服务器,可在.htaccess中添加:
    LimitRequestBody 209715200
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:17:02