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

DRF结合Serializer返回多模型自定义数据触发KeyError问题

问题成因
  • 数据结构不匹配:你构造的options是包含两个独立字典的列表,每个字典仅包含一个键,序列化器需要同时读取albums和genres两个字段,读取缺失字段时就会触发KeyError。
  • 序列化器字段定义错误:你需要返回的是字符串列表,而不是单个字符串,用CharField无法适配列表结构;另外普通Serializer不需要声明Meta类指定字段,该配置仅对ModelSerializer生效。
  • 数据源未做字段提取:直接传入模型QuerySet给序列化器,不会自动提取你需要的album_name、genre_name属性。
  • 序列化参数和方法误用:设置many=True会序列化列表结构,和你需要的单个对象返回结构不符;且序列化(将Python对象转为响应数据)过程不需要调用is_valid(),该方法仅用于反序列化(接收前端数据入库)时的校验。
  • 额外拼写问题:Album模型中genre外键的on_delete参数里nodels是拼写错误,应为models。
修复代码

序列化器修改

from rest_framework import serializers

class InfoSerializer(serializers.Serializer):
    albums = serializers.ListField(child=serializers.CharField())
    genres = serializers.ListField(child=serializers.CharField())

视图集修改

from rest_framework.views import ViewSet
from rest_framework.response import Response
from .models import Album, Genre

class OptionsViewSet(ViewSet):
    serializer_class = InfoSerializer

    def list(self, request):
        # 直接提取对应字段生成列表
        res_data = {
            "albums": list(Album.objects.values_list("album_name", flat=True)),
            "genres": list(Genre.objects.values_list("genre_name", flat=True))
        }
        serializer = InfoSerializer(res_data)
        return Response(serializer.data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:12:02