Django数据入库报错:Basetable接收到意外关键字参数
Django嵌套数据序列化存储报错解决
报错信息
TypeError: Basetable() got unexpected keyword arguments: 'CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents'
需求数据
需存入数据库的JSON结构:
jsonToUse = { "CompanyId": "320193", "CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents": [ { "decimals": "-6", "unitRef": "usd", "value": "39789000000" }, { "decimals": "-6", "unitRef": "usd", "value": "50224000000" }, { "decimals": "-6", "unitRef": "usd", "value": "25913000000" }, { "decimals": "-6", "unitRef": "usd", "value": "35929000000" } ] }
当前Model定义
class Basetable(models.Model): basetable_id = models.AutoField(primary_key=True) CompanyId = models.IntegerField() class Cashcashequivalentsrestrictedcashandrestrictedcashequivalents(models.Model): cashcashequivalentsrestrictedcashandrestrictedcashequivalents_id = models.AutoField( primary_key=True) unitRef = models.CharField(max_length=100) value = models.CharField(max_length=100) decimals = models.IntegerField() basetable_id = models.ForeignKey(Basetable, on_delete=models.CASCADE)
当前Serializer定义
class CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalentsSerializer(serializers.ModelSerializer): class Meta: model = Cashcashequivalentsrestrictedcashandrestrictedcashequivalents fields = ['decimals', 'unitRef', 'value'] class CashFlowSerializer(serializers.ModelSerializer): CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents = CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalentsSerializer( many=True) class Meta: model = Basetable fields = "__all__"
当前View代码片段
.....#TRIMMED GET SYNTAX..... check = CashFlowSerializer(data=jsonToUse) if (check.is_valid(raise_exception=True)): print("ready to send to db") check.save() return JsonResponse(jsonToUse, safe=False)
解决方案
报错原因是:Basetable模型本身没有CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents字段,默认的save()方法会尝试把这个嵌套字段传给Basetable构造函数,导致参数不匹配。需要重写序列化器的create方法,手动处理嵌套数据的保存:
修改Serializer代码
class CashFlowSerializer(serializers.ModelSerializer): CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents = CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalentsSerializer( many=True) class Meta: model = Basetable fields = "__all__" def create(self, validated_data): # 取出嵌套的现金数据并从主数据中移除 cash_data = validated_data.pop('CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents') # 创建主表Basetable实例 basetable = Basetable.objects.create(**validated_data) # 遍历嵌套数据,创建关联的子表实例 for cash_item in cash_data: # 将JSON中的字符串类型decimals转为整数,匹配Model字段类型 cash_item['decimals'] = int(cash_item['decimals']) Cashcashequivalentsrestrictedcashandrestrictedcashequivalents.objects.create( basetable_id=basetable, **cash_item ) return basetable
额外注意事项
- JSON中的
decimals是字符串格式(如"-6"),但Model定义为IntegerField,必须手动转换类型,否则会触发类型错误。 - 子表的外键字段
basetable_id需要传入Basetable实例,而非ID值。
修改后,调用check.save()会先创建主表数据,再循环创建关联的子表数据,即可完成嵌套JSON的数据库存储。
内容的提问来源于stack exchange,提问作者Maddy
相关产品推荐
相关产品推荐

