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

Django DRF调用serializer.is_valid()返回500内部服务器错误求助

问题原因及修复方案

核心问题1:序列化器传参错误

DRF的ModelSerializer初始化时,第一个位置参数默认是实例对象(用于序列化查询结果),如果是用于创建数据的反序列化场景,必须显式用data关键字参数传递请求数据;上传文件的场景还需要额外传递files参数对应request.FILES,原有写法会导致序列化器逻辑错乱抛出异常。

核心问题2:前端请求头配置错误

使用axios发送FormData格式请求时,禁止手动设置Content-Type: multipart/form-data。浏览器会自动生成该请求头,并且自动添加表单分隔用的boundary参数,手动设置会丢失boundary,导致Django无法正常解析上传的文件和表单数据。

可选配置检查

确认Django项目配置了媒体文件相关参数:

  1. settings.py中添加以下配置:
import os
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
  1. 项目根目录urls.py中添加媒体文件访问路由(开发环境用):
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 原有路由配置
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

修复后的代码

前端color.js修改

删除手动设置的Content-Type请求头:

function PersonalColorScreen({navigation,route}) {
    const {image} = route.params;
    console.log('uri is', image.uri);
    const [userToken, setUserToken] = React.useState(route.params?.userToken);

    // 移除手动设置的Content-Type
    const requestHeaders = {}
    // helper function: generate a new file from base64 String
    //convert base64 image data to file object to pass it onto imagefield of serializer.
    //otherwise, serializer outputs 500 Internal server error code

    const dataURLtoFile = (dataurl, filename) => {
    const arr = dataurl.split(',')
    const mime = arr[0].match(/:(.*?);/)[1]
    const bstr = atob(arr[1])
    let n = bstr.length
    const u8arr = new Uint8Array(n)
    while (n) {
      u8arr[n - 1] = bstr.charCodeAt(n - 1)
      n -= 1 // to make eslint happy
    }
    return new File([u8arr], filename, { type: mime })
  }
  //random number between 0-9
  function getRandomInt(max) {
    return Math.floor(Math.random() * max);
  }
  
  // generate file from base64 string
  const file = dataURLtoFile(image.uri, `${getRandomInt(10)}.png`)
  const formData= new FormData();
  formData.append('img',file,file.name);

  console.log(file.name);
    //axios post request to send data
    axios.post('http://localhost:8000/accounts/personalcolor/', formData, requestHeaders)
    .then(res => {
        console.log(res);
        if (res.data === 'upload another image') {
            setimageError('upload another image');
        } else {
            // signUp(userToken);
            let color;
            switch (res.data){
                case ('spring'):
                    color = 'spring';
                    break;
                case ('summer'):
                    color = 'summer';
                    break;
                case ('fall'):
                    color = 'fall';
                    break;
                case ('winter'):
                    color = 'winter';
                    break;
            }
        }
        })
    .catch(err => {
        console.error(err.response.data)
    })

后端view.py修改

修正序列化器传参,开启数据保存逻辑:

@api_view(['POST'])
def personalcolor(request):
    # 显式传递data和files参数,修复缩进错误
    serializer = ColorSerializer(data=request.data, files=request.FILES)
    # validation of input data,添加raise_exception=True避免未捕获异常抛出500
    if serializer.is_valid(raise_exception=True):
        # 取消注释保存数据,才会将图片存入media目录
        instance = serializer.save()
        # 可直接通过instance.img.url获取上传后的图片访问路径
        return Response(serializer.data, status = status.HTTP_201_CREATED)
    else:
        return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)

排查小技巧

如果修改后仍然报错,直接查看Django启动runserver的终端输出,500错误会打印完整的错误栈,可快速定位是权限问题、目录不存在问题还是其他配置问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:00:03