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

Django多表查询触发KeyError问题求助(新手)

解决Django跨表查询触发KeyError的问题

嘿,我来帮你捋清楚这个问题的根源和解决办法,你遇到的KeyError其实是因为queryset返回格式和序列化器的预期不匹配导致的,咱们一步步来搞定:

问题出在哪?

你在视图集的queryset里用了values('dateAjout','idRecruteur__entrepriseName'),这会让Django返回一个字典列表(而不是Offre模型的实例)。但你的OffreSerializer是继承自ModelSerializer,它默认会根据Offre模型的字段去读取数据——可idRecruteur__entrepriseName并不是Offre模型的直接字段,序列化器找不到这个键,自然就抛出KeyError了。

另外注意下你的Recruteur模型代码里写的是name = models.CharField(...),但你在values里用的是idRecruteur__entrepriseName,这里大概率是笔误,后面的示例我假设Recruteur模型里确实有entrepriseName字段,或者你可以把它改成idRecruteur__name来匹配实际字段。

解决方案1:用ModelSerializer处理关联字段(推荐)

这种方式更符合DRF的最佳实践,让序列化器来处理跨表关联,而不是在queryset里用values:

1. 修改序列化器serualizers.py

添加关联字段来获取Recruteur的企业名称:

class OffreSerializer(serializers.ModelSerializer):
    # 通过source指定关联模型的字段,读取Recruteur的entrepriseName
    entreprise_name = serializers.StringRelatedField(source='idRecruteur.entrepriseName', read_only=True)
    
    class Meta:
        model = Offre
        # 明确指定需要的字段,比__all__更清晰可控
        fields = ['dateAjout', 'entreprise_name']

2. 修改视图集的queryset

去掉values(),直接过滤即可,DRF会自动处理关联查询:

class OffreViewSet(ModelViewSet):
    queryset = Offre.objects.filter(idRecruteur=1)
    serializer_class = OffreSerializer

解决方案2:如果一定要用values(),改用普通Serializer

如果你坚持要用values()返回字典,那需要把序列化器改成普通的Serializer,手动定义所有需要的字段:

class OffreSerializer(serializers.Serializer):
    dateAjout = serializers.DateTimeField()
    idRecruteur__entrepriseName = serializers.CharField()

视图集的queryset保持不变,但要确保字段名完全匹配:

class OffreViewSet(ModelViewSet):
    queryset = Offre.objects.filter(idRecruteur=1).values('dateAjout','idRecruteur__entrepriseName')
    serializer_class = OffreSerializer

额外小提醒

  • 尽量避免在ModelSerializer中混用values(),因为ModelSerializer是为模型实例设计的,用values()会绕过模型的很多特性(比如信号、字段验证等)
  • 检查你的Recruteur模型字段名,确保entrepriseName确实存在,或者改成你实际定义的字段名(比如name)

内容的提问来源于stack exchange,提问作者M1rwen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:26:14