Django Annotation用字典值报错:KeyError: F(fk_security__ticker_symbol)
问题原因
你直接用F("fk_security__ticker_symbol")作为字典键是错误的——F()返回的是Django的数据库表达式对象,不是实际的字符串ticker值。Python会把这个F对象本身当成键去查询tickers字典,而你的字典里只有"BCO"、"AIR"这类字符串键,自然找不到对应值,触发KeyError。
实现方案
要完成这个需求,得用Django的Case和When做数据库层面的条件映射,把字典里的ticker-price对应关系转换成SQL的CASE语句。
具体代码示例:
from django.db.models import Case, When, FloatField tickers = { "BCO": 10.0, "AIR": 50.0, } # 为每个ticker构建对应的匹配条件 when_clauses = [When(fk_security__ticker_symbol=ticker, then=price) for ticker, price in tickers.items()] # 用Case组合所有条件,设置默认返回值 assets = Asset.objects.annotate( price=Case(*when_clauses, default=None, output_field=FloatField()) )
代码说明
When会针对每个ticker值设置匹配规则,命中时返回对应的price。Case将所有When条件整合,default用来处理不在tickers字典里的ticker(比如返回None),output_field指定返回值的字段类型(这里是浮点型)。- 这种方式会在数据库查询阶段自动匹配每个Asset关联的Security的ticker_symbol,返回对应的price值,不会再触发KeyError。
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

