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

Flutter发送Uint8List签名图片至Django ImageField存储失败问题

问题根因

数据库中存储PNG二进制乱码、无法生成可访问图片文件,核心是两处逻辑错误:

  • Flutter端构造Multipart上传文件时,未指定带后缀的文件名与图片MIME类型,Django无法识别该请求为文件上传请求
  • Django端未配置multipart格式解析器,且错误从request.data中读取原始二进制内容直接赋值给ImageField,完全跳过Django内置的文件存储、文件名生成、路径拼接逻辑,ImageField无法正常处理原始字节数据
修复方案

1. 调整Flutter端上传代码

补全文件上传必要参数,同时补上缺失的请求发送逻辑,修改后代码如下:

// 顶部需要先导入依赖
import 'package:http_parser/http_parser.dart';

signaturePic(String imgName, SignatureController controller) async{
  String completeUrl = '$rootApi/reports/signature_pic/';
  var uri = Uri.parse(completeUrl);
  var request = http.MultipartRequest("POST", uri);
  Uint8List? signatureFile = await controller.toPngBytes();    
  if (signatureFile != null){
    final multipartFile = http.MultipartFile.fromBytes(
      imgName, 
      signatureFile,
      filename: '$imgName.png', // 必须传入带.png后缀的文件名
      contentType: MediaType('image', 'png'), // 明确指定文件MIME类型为PNG图片
    );
    request.files.add(multipartFile);
    request.headers["authorization"]='TOKEN ${temp.apiKey}';
  }
  // 原代码缺失请求发送逻辑,必须补上
  var streamedResponse = await request.send();
  var response = await http.Response.fromStream(streamedResponse);
  debugPrint('上传返回结果:${response.body}');
}

2. 调整Django端视图代码

添加multipart格式解析器,从request.FILES中读取标准上传文件对象再赋值给ImageField,修改后代码如下:

from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

class SignaturePicView(APIView):
    # 添加multipart解析器,否则DRF无法正确解析上传的文件
    parser_classes = [MultiPartParser, FormParser]

    def post(self, request):
        try:
            # 上传的文件统一存放在request.FILES中,字段名与Flutter端传入的MultipartFile字段名一致
            for field_name, uploaded_file in request.FILES.items():
                items = field_name.split('__')
                is_return = True if items[5] == 'True' else False

                SignaturePic.objects.update_or_create(
                    user=request.user, # 直接使用request.user即可,无需重复查询数据库
                    unique_identifier=field_name,
                    is_return=is_return,
                    defaults={
                        'image': uploaded_file, # 传入Django标准UploadedFile对象,ImageField会自动完成存储
                    }
                )
            return Response(status=status.HTTP_201_CREATED)

        except Exception as e:
            print(e)
            return Response(status=status.HTTP_400_BAD_REQUEST, data={'error': str(e)})
验证标准

代码调整完成后重新发起上传请求,符合以下表现即为修复成功:

  • 数据库SignaturePic表的image字段存储的是类似signatures/xxx.png的相对路径字符串,不再是二进制乱码
  • Django配置的MEDIA_ROOT路径下的signatures目录中,会生成对应的实体PNG文件,可通过配置的MEDIA_URL正常访问

注意:提前确认Django配置文件中MEDIA_URL、MEDIA_ROOT配置正确,开发环境下需要在urls.py中添加媒体文件的路由映射,否则上传后的图片无法通过HTTP正常访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:24:15