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

