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

不使用原生SQL实现DRF嵌套序列化:获取指定用户关联问卷及嵌套答案

实现方案

第一步:优化ORM查询

优先使用Django自带的关联查询+预取机制,避免N+1查询问题,同时过滤出仅包含目标用户答案的问卷,只拉取需要的字段降低开销:

from django.db.models import Prefetch

target_user_id = "你要查询的用户ID"
polls = Poll.objects.filter(
    pollanswer__user_id=target_user_id
).distinct().prefetch_related(
    Prefetch(
        # 如果你给ForeignKey设置了related_name,这里替换为自定义的related_name
        "pollanswer_set",
        # 仅预取目标用户的答案
        queryset=PollAnswer.objects.filter(user_id=target_user_id).only("id", "text"),
        to_attr="user_answers"
    )
)

第二步:编写对应序列化器

直接基于Poll模型编写序列化器,用SerializerMethodField自定义answers字段的返回格式:

from rest_framework import serializers

class PollWithUserAnswerSerializer(serializers.ModelSerializer):
    # 映射id字段为返回要求的poll_id
    poll_id = serializers.IntegerField(source="id")
    answers = serializers.SerializerMethodField()

    class Meta:
        model = Poll
        fields = ["poll_id", "answers"]
    
    def get_answers(self, obj):
        answer_dict = {}
        # 直接读取预取好的答案,不会触发额外查询
        for index, answer in enumerate(obj.user_answers):
            # 按你要求的格式拼接key,也可以替换为answer.id作为序号
            key = f"{target_user_id}_answer{index+1}"
            answer_dict[key] = answer.text
        return answer_dict

第三步:视图调用示例

from rest_framework.views import APIView
from rest_framework.response import Response

class UserPollAnswerView(APIView):
    def get(self, request):
        target_user_id = request.query_params.get("user_id")
        if not target_user_id:
            return Response({"error": "缺少user_id参数"}, status=400)
        # 执行查询逻辑
        polls = Poll.objects.filter(
            pollanswer__user_id=target_user_id
        ).distinct().prefetch_related(
            Prefetch(
                "pollanswer_set",
                queryset=PollAnswer.objects.filter(user_id=target_user_id).only("id", "text"),
                to_attr="user_answers"
            )
        )
        serializer = PollWithUserAnswerSerializer(polls, many=True)
        return Response(serializer.data)
Django ORM学习指南推荐
  • 优先通读Django官方文档的ORM模块,覆盖基础查询、关联查询、性能优化、查询表达式等核心内容,是最权威的学习资料
  • DRF序列化器相关内容直接学习DRF官方文档的序列化器章节,重点掌握嵌套序列化、自定义字段、方法字段的使用规则
  • 日常多做关联模型的查询、序列化实战练习,遇到问题优先排查字段定义、查询逻辑的参数配置

内容的提问来源于stack exchange,提问作者swats-the-floran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 03:54:03