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

Django嵌套序列化器PUT方法报错:QuerySet对象无answer属性

问题现象

Django REST Framework 项目中更新嵌套序列化器时抛出AttributeError,错误提示为'QuerySet' object has no attribute 'answer',对应PUT请求接口/quiz/q/django/1/返回500状态码。
核心报错栈关键片段:

File "C:\Users\HP\Desktop\roy\project\HelpMe\sunny\backend\quiz\serializers.py", line 47, in update
    answer = instance.answer.all()
AttributeError: 'QuerySet' object has no attribute 'answer'
报错根因

一共两处代码逻辑错误:

  • 视图层查询目标Question对象时使用了filter()方法,该方法返回的是QuerySet集合(即使匹配到唯一ID的结果,也是集合类型,不是单个模型实例),传给序列化器后,序列化器update方法拿到的instance是QuerySet,自然无法访问单个实例才有的反向关联属性answer。
  • 序列化器的update方法本身存在次级逻辑错误:将关联answer转成list类型后,错误地对list对象调用.objects.get()方法,list类型没有objects属性,就算解决了前面的QuerySet问题,这里也会触发新的报错。
修复方案

1. 修改视图层代码

将查询单个实例的filter()方法替换为get_object_or_404(),既可以返回单个模型实例,也能在ID对应记录不存在时自动返回404响应,修复后的视图代码:

from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from .models import Question
from .serializers import QuestionSerializer

class QuizQuestionDetail(APIView):

    def get(self, request, format=None, **kwargs):
        quizz = get_object_or_404(Question, id=kwargs['pk'])
        serializer = QuestionSerializer(quizz)
        return Response(serializer.data)

    def put(self, request, format=None, **kwargs):
        quizz = get_object_or_404(Question, id=kwargs['pk'])
        serializer = QuestionSerializer(quizz, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

注意:GET接口原来传了many=True是因为查询结果是QuerySet,改成单个实例后要去掉many=True参数,否则序列化器会把单个实例当列表处理。

2. 修改序列化器update方法

修正answer查询、更新的逻辑,不要对list类型调用ORM方法,修复后的update方法代码:

def update(self, instance, validated_data):
    answers_data = validated_data.pop('answer')
    # 先更新Question本身的字段
    instance.quiz = validated_data.get('quiz', instance.quiz)
    instance.title = validated_data.get('title', instance.title)
    instance.save()

    # 遍历更新关联的Answer
    for answer_data in answers_data:
        # 直接通过Answer模型用id查询,不要对list调用objects方法
        answer_obj = Answer.objects.get(pk=answer_data['id'], question=instance)
        answer_obj.answer_text = answer_data.get('answer_text', answer_obj.answer_text)
        answer_obj.is_right = answer_data.get('is_right', answer_obj.is_right)
        answer_obj.save()
    return instance

补充:查询Answer时加上question=instance过滤条件,可以避免越权修改不属于当前问题的答案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:51:21