通过Django API从TS上传BLOB至数据库时字段为空的问题排查
问题排查与解决:Django BinaryField 上传后为空
核心问题分析
你遇到的是前端上传UInt8Array转Blob后,Django模型的log_adjustment_blob(BinaryField)始终为空,但其他字段正常的问题。核心原因大概率是后端没有正确读取上传的文件内容并转换为字节存入BinaryField,或者前端FormData的上传格式有细节遗漏。
分步解决
1. 前端代码调整:确保Blob上传格式正确
先确认locAdjustmentBlob是有效的UInt8Array(打印locAdjustmentBlob.length验证非空),然后调整FormData的append方式,添加文件名参数帮助后端识别文件:
// 明确指定Blob的MIME类型,添加文件名参数 const test = new Blob([locAdjustmentBlob], { type: 'application/octet-stream' }); const formData = new FormData(); formData.append("log_user", locUser); // 第三个参数指定文件名,后端更容易识别为文件上传 formData.append("log_adjustment_blob", test, "log.csv"); await store.state.apiHandler.postForm("/raw/logs/", formData);
注意:不要手动设置请求的
Content-Type,FormData会自动生成正确的multipart/form-data头部。
2. 后端代码修正:正确处理文件内容存入BinaryField
BinaryField存储的是字节数据,而FormData上传的文件在Django中是UploadedFile对象,必须读取其内容才能存入字段。以下分两种场景给出代码:
场景1:使用Django REST Framework(DRF)
修改序列化器,将上传的文件内容转为字节后存入模型:
from rest_framework import serializers from .models import Log class LogSerializer(serializers.ModelSerializer): # 用FileField接收上传的文件 log_adjustment_blob = serializers.FileField() class Meta: model = Log fields = ['log_user', 'log_adjustment_blob'] def create(self, validated_data): # 取出上传的文件对象,读取字节内容 blob_file = validated_data.pop('log_adjustment_blob') validated_data['log_adjustment_blob'] = blob_file.read() return super().create(validated_data)
对应的视图可以用CreateAPIView:
from rest_framework.generics import CreateAPIView from .models import Log from .serializers import LogSerializer class LogCreateView(CreateAPIView): queryset = Log.objects.all() serializer_class = LogSerializer
场景2:使用普通Django视图
直接从request.FILES中获取文件,读取内容后创建模型实例:
from django.http import HttpResponse from .models import Log def upload_log(request): if request.method == 'POST': log_user = request.POST.get('log_user') blob_file = request.FILES.get('log_adjustment_blob') if log_user and blob_file: # 读取文件的字节内容 blob_content = blob_file.read() Log.objects.create(log_user=log_user, log_adjustment_blob=blob_content) return HttpResponse("上传成功") return HttpResponse("参数缺失")
3. 额外验证步骤
- 检查Django模型的
BinaryField是否允许为空:如果需要强制非空,修改模型为log_adjustment_blob = models.BinaryField(null=False, blank=False) - 在后端打印
blob_content的长度,确认读取到了非空的字节数据 - 用Postman直接模拟上传:上传一个csv文件到接口,验证后端是否能正确存入,排除前端代码问题
内容的提问来源于stack exchange,提问作者KSler
相关产品推荐
相关产品推荐

