Django DRF序列化报错'QuerySet无experience_in_years属性'如何解决
问题原因
- 视图逻辑错误:
ExpertPricing.objects.filter()返回的是QuerySet查询集对象,哪怕查询结果只有1条,它也不是单个ExpertPricing模型实例。你把多个QuerySet对象塞进data_list后传给序列化器,序列化器的many=True仅会遍历外层列表,无法识别内层的QuerySet,所以尝试读取QuerySet的experience_in_years字段时直接报错。 - 序列化器字段配置不匹配:你在
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
相关产品推荐
相关产品推荐

