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

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字段:

  1. 确保Usermanagement中存在createdby=0的记录
  2. 按如下方式创建实例:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:45:54