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

Django DRF序列化报错'QuerySet无experience_in_years属性'如何解决

问题原因
  1. 视图逻辑错误:ExpertPricing.objects.filter()返回的是QuerySet查询集对象,哪怕查询结果只有1条,它也不是单个ExpertPricing模型实例。你把多个QuerySet对象塞进data_list后传给序列化器,序列化器的many=True仅会遍历外层列表,无法识别内层的QuerySet,所以尝试读取QuerySet的experience_in_years字段时直接报错。
  2. 序列化器字段配置不匹配:你在ExpertPricing模型中关联JobRole的外键字段名为role_name,但序列化器中自定义的关联字段名为role,没有指定source参数的情况下,序列化器会尝试从模型实例读取role属性,该属性仅用于反向查询,正向访问不存在,即使视图逻辑修好了后续也会报错。
解决方法

第一步:修正视图查询逻辑

因为ExpertPricing的role_name和technology都是OneToOneField,符合条件的记录最多只有1条,你可以把filter()改为first()直接取单个实例,不存在则返回None,避免塞入QuerySet。修改后的视图代码如下:

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import JobRole, Technology, ExpertPricing
from .serializers import ExpertPricingSerializer

class PricingView(APIView):
    def post(self, request):
        datas = request.data
        data_list = []
        for data in datas:
            job_role_id = data["job_role"]
            technology_id = data["technology"]
            # 增加异常捕获,避免传入的id不存在时报错
            try:
                job_role = JobRole.objects.get(pk=job_role_id)
                technology = Technology.objects.get(pk=technology_id)
                # 取单个实例,而不是QuerySet
                expert_pricing = ExpertPricing.objects.filter(
                    role_name=job_role, 
                    technology=technology
                ).first()
                if expert_pricing:
                    data_list.append(expert_pricing)
            except (JobRole.DoesNotExist, Technology.DoesNotExist):
                # 不存在的id直接跳过即可,也可以根据需求返回错误提示
                continue
        serializer = ExpertPricingSerializer(data_list, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

第二步:修正序列化器配置

给自定义的role字段增加source参数,指定对应模型的外键字段名,或者直接把字段名改为和模型一致的role_name。修改后的序列化器代码如下:

class ExpertPricingSerializer(serializers.ModelSerializer):
    # source参数指定该字段对应模型上的role_name外键字段
    role = JobRoleSerializer(read_only=True, source="role_name")
    technology = TechnologySerializer(read_only=True)
    class Meta:
        model = ExpertPricing
        # 显式指定字段,避免返回多余的role_name外键id
        fields = ["id", "role", "technology", "experience_in_years", "salary_per_month"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:27:00