使用Django REST Framework+MongoEngine遇ValueError错误求助
解决MongoEngine + Django REST Framework 中的 ValueError: The source SON object needs to be of type 'dict'
我帮你排查了代码里的几个关键问题,这些正是触发这个错误的根源,咱们一步步来修正:
1. FloatField 默认值类型不匹配
你的ImageRecognition模型中,ddPercent是FloatField,但默认值设成了空字符串'':
ddPercent = fields.FloatField(required=False, default='')
MongoEngine期望这个字段存储数值类型,但空字符串会导致MongoDB中存储的类型不兼容,序列化时就会抛出SON对象类型错误。
修正方案:把默认值改成数值类型,比如0.0或者None(如果允许字段为空的话):
ddPercent = fields.FloatField(required=False, default=0.0)
2. ListField 传入了单个字典而非列表
在视图保存土豆数据时,你给jvv传了单个字典:
ImageRecognition(imageUrl='土豆', ddPercent=8.22, jvv={'unit':'m', 'unitValue':12}).save()
但模型里jvv定义的是ListField(fields.EmbeddedDocumentField(Jvv)),必须传入包含字典的列表,哪怕只有一个元素。单个字典无法匹配列表类型,会导致MongoEngine解析SON对象时出错。
修正方案:用列表包裹字典:
ImageRecognition( imageUrl='土豆', ddPercent=8.22, jvv=[{'unit':'m', 'unitValue':12}] ).save()
3. DateTimeField 默认值的潜在问题(非直接错误,但需修正)
模型中createTime的默认值用了datetime.now():
createTime = fields.DateTimeField(default=datetime.now())
这会导致所有新创建的实例都使用服务器启动时的时间,而不是实例创建的时间。正确的做法是传递函数引用,让MongoEngine在创建实例时才调用函数:
createTime = fields.DateTimeField(default=datetime.now)
完整修正后的代码
模型代码
from datetime import datetime from mongoengine import Document, EmbeddedDocument, fields class Jvv(EmbeddedDocument): unit = fields.StringField() unitValue = fields.IntField() class ImageRecognition(Document): imageUrl = fields.StringField(default='', max_length=100) createTime = fields.DateTimeField(default=datetime.now) ddPercent = fields.FloatField(required=False, default=0.0) jvv = fields.ListField(fields.EmbeddedDocumentField(Jvv)) def __str__(self): return self.imageUrl class Meta: db_table = 'imagerecognition'
视图代码(关键部分修正)
class ImageUrlSave(views.APIView): def get(self, request, *args, **kwargs): imgs = ImageRecognition.objects(imageUrl='白菜') serializer = ImageUrlSerializer(imgs, many=True) # 修正jvv为列表格式 ImageRecognition( imageUrl='土豆', ddPercent=8.22, jvv=[{'unit':'m', 'unitValue':12}] ).save() data = serializer.data return Response({ 'msg': 'SUCCESS', 'code_status': 1000, 'result': data })
额外注意事项
如果你的MongoDB中已经存在错误类型的数据(比如ddPercent字段存了字符串),需要先清理这些数据,或者在序列化时添加兼容处理,否则旧数据依然会触发相同的错误。
内容的提问来源于stack exchange,提问作者Lois.su
相关产品推荐
相关产品推荐

