Django插入数据时触发KeyError: 'createdby'问题求助
问题根源分析
1. 外键to_field配置与赋值逻辑不匹配
Inquery模型中createdby和modifiedby外键的to_field参数指定关联Usermanagement的createdby/modifiedby字段,但你在创建Inquery实例时,传入的是Usermanagement(userid=0)——这个临时实例既未保存到数据库,也未设置createdby字段值。Django处理外键关联时,会尝试基于to_field指定的字段缓存关联对象,由于该字段值缺失,最终在清理缓存时找不到对应的createdby缓存键,抛出KeyError。
另外,Usermanagement的主键是userid,但你强行指定外键关联其createdby字段,这与常规外键关联主键的逻辑冲突,进一步加剧了缓存处理的异常。
2. 临时未保存实例的误用
你使用Airport(airportid=1)、Usermanagement(userid=0)这类方式创建未保存的模型实例作为外键值,Django无法为这类实例建立有效的关联缓存,这也是触发报错的重要原因。
解决方案
方案1:修正外键关联逻辑(推荐)
如果Inquery表的CreatedBy字段实际存储的是Usermanagement的主键userid,移除to_field参数,让外键默认关联主键:
# freight/models.py 中修改Inquery的两个外键字段 createdby = models.ForeignKey('accounts.Usermanagement', on_delete=models.CASCADE, db_column='CreatedBy', related_name="Usermanagement_Inquery_createdby") modifiedby = models.ForeignKey('accounts.Usermanagement', on_delete=models.CASCADE, db_column='ModifiedBy', related_name="Usermanagement_Inquery_modifiedby")
然后使用已存在的数据库实例创建Inquery:
from accounts.models import Usermanagement from freight.models import Inquery, Airport, Stage, Customer # 获取数据库中已存在的实例(确保记录存在) user = Usermanagement.objects.get(userid=0) source_airport = Airport.objects.get(airportid=1) dest_airport = Airport.objects.get(airportid=21) stage = Stage.objects.get(stageid=1) customer = Customer.objects.get(customerid=1) i = Inquery( inqueryid=6, inquerynumber="INQ765758499", sourceairportid=source_airport, destinationairportid=dest_airport, stageid=stage, commoditytypeid=6, customerid=customer, branchid=1, transactiontype="AGENT", businesstype="Self", hodate="2020-11-18", totalshipmentunits="56", # 注意模型中该字段为CharField,需传字符串 unitid="100", # 同上 grossweight=100, volumemetricweight=100, remark="test", dateofcreation="2018-11-20 00:00:00", dateofmodification="2018-11-20 00:00:00", createdby=user, modifiedby=user, isactive=1 # 补充必填的isactive字段 ) i.save()
方案2:坚持关联Usermanagement的createdby字段
如果数据库设计确实要求Inquery关联Usermanagement的createdby字段:
- 确保Usermanagement中存在
createdby=0的记录 - 按如下方式创建实例:
from accounts.models import Usermanagement from freight.models import Inquery # 通过createdby字段获取已存在的用户实例 user = Usermanagement.objects.get(createdby=0) i = Inquery( # 其他字段参考方案1填写 createdby=user, modifiedby=user, isactive=1 ) i.save()
额外注意事项
- 禁止使用未保存的临时实例作为外键值,必须通过
objects.get()或objects.filter()获取数据库中已存在的记录 - 检查模型所有必填字段是否都传入有效值,比如你之前的代码遗漏了
isactive字段 - 由于Inquery模型设置了
managed=False,修改模型字段后需手动同步数据库结构
内容的提问来源于stack exchange,提问作者Nipun
相关产品推荐
相关产品推荐

