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

Django调用get_beneficiary时出现TypeError: unhashable type: 'slice'错误求排查

错误原因

TypeError: unhashable type: 'slice'报错由以下核心问题导致:

  • Django REST Framework 的 GenericViewSet 要求 get_queryset 方法必须返回 Django QuerySet 对象,你当前重写的方法返回的是自定义字典结构
  • DRF 内部处理列表查询的分页、排序逻辑时,会对 get_queryset 返回的结果执行切片操作(格式为 queryset[起始索引:结束索引]),字典不支持切片操作,且切片对象无法作为字典的key,因此抛出该错误
  • 额外存在性能问题:get_beneficiary 方法中遍历受益人数据时,每次循环都单独执行一次数据库count查询,N个受益人会产生N次额外数据库查询,存在N+1性能缺陷。
修复方案

根据业务需求可选以下两种修复方式:

方案1:保留自定义返回结构,调整逻辑位置

不要重写get_queryset方法,将自定义返回逻辑放到list方法中实现:

class ListView(ResponseViewMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    serializer_class = CourseFilterSerializer
    queryset = Course.objects.all()

    def list(self, request, *args, **kwargs):
        common_data = self.get_queryset()
        course_beneficiaries = get_beneficiary(common_data)
        return Response({
            "course_beneficiaries": course_beneficiaries,
        })

如果需要同时返回原Course列表数据,可以调整为:

def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())
    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        course_data = self.get_paginated_response(serializer.data).data
    else:
        serializer = self.get_serializer(queryset, many=True)
        course_data = serializer.data
    
    course_beneficiaries = get_beneficiary(queryset)
    course_data["course_beneficiaries"] = course_beneficiaries
    return Response(course_data)

方案2:优化统计逻辑,解决N+1性能问题

使用Django聚合查询一次性统计所有受益人的关联课程数,无需循环查询数据库:

from django.db.models import Count

def get_beneficiary():
    # 注:Count的参数为Course模型中关联Beneficiary外键的related_name值,默认未设置时为course_set
    beneficiary_list = Beneficiary.objects.annotate(
        course_count=Count('course_set')
    ).values('beneficiary_name', 'course_count')
    return [
        {"name": item["beneficiary_name"], "count": item["course_count"]}
        for item in beneficiary_list
    ]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:42:01