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

DRF中如何序列化含多类型问题的Test模型?已编写各问题序列化器

解决方案

模型无需重构,可先做小优化

你的模型设计(用多表继承区分问题类型)是可行的,不需要重构,但可以加个小优化避免类型不匹配:给每个问题子类重写save方法,自动设置对应的type字段,确保数据一致性:

class TextQuestion(Question):
    answer = models.CharField(max_length=255)  # 原代码未指定max_length,Django会报错,需补上

    def save(self, *args, **kwargs):
        self.type = Question.Type.TEXT
        super().save(*args, **kwargs)

class RadioQuestion(Question):
    variants = fields.ArrayField(models.CharField(max_length=255))
    answer = models.CharField(max_length=255)

    def save(self, *args, **kwargs):
        self.type = Question.Type.RADIO
        super().save(*args, **kwargs)

class ChoiceQuestion(Question):
    variants = fields.ArrayField(models.CharField(max_length=255))
    answers = fields.ArrayField(models.CharField(max_length=255))

    def save(self, *args, **kwargs):
        self.type = Question.Type.CHOICE
        super().save(*args, **kwargs)

用SerializerMethodField处理多类型问题序列化

你担心SerializerMethodField不能配合many=True是误解,完全可以实现。只需在TestSerializer中定义该字段,然后在对应的方法里遍历每个问题,根据类型选择序列化器即可:

from rest_framework import serializers
from .models import Test
from .serializers import TextQuestionSerializer, RadioQuestionSerializer, ChoiceQuestionSerializer

class TestSerializer(serializers.ModelSerializer):
    questions = serializers.SerializerMethodField()

    class Meta:
        model = Test
        fields = ['name', 'creator', 'questions']

    def get_questions(self, obj):
        serialized_list = []
        # 遍历关联的所有Question实例
        for question in obj.questions.all():
            # 根据type字段匹配对应的子类序列化器
            if question.type == question.Type.TEXT:
                # 多表继承下,通过子类小写名称的属性获取子类实例
                serializer = TextQuestionSerializer(question.textquestion)
            elif question.type == question.Type.RADIO:
                serializer = RadioQuestionSerializer(question.radioquestion)
            elif question.type == question.Type.CHOICE:
                serializer = ChoiceQuestionSerializer(question.choicequestion)
            else:
                continue  # 可根据需求处理未知类型
            serialized_list.append(serializer.data)
        return serialized_list

可选:用第三方库简化多态序列化

如果觉得手动判断麻烦,可以用django-rest-polymorphic库,它专门处理DRF中的多态模型序列化。安装后只需定义一个多态序列化器,关联各个子类的序列化器,就能自动匹配:

from rest_polymorphic.serializers import PolymorphicSerializer

class QuestionPolymorphicSerializer(PolymorphicSerializer):
    model_serializer_mapping = {
        TextQuestion: TextQuestionSerializer,
        RadioQuestion: RadioQuestionSerializer,
        ChoiceQuestion: ChoiceQuestionSerializer,
    }

# 然后在TestSerializer中直接使用
class TestSerializer(serializers.ModelSerializer):
    questions = QuestionPolymorphicSerializer(many=True)

    class Meta:
        model = Test
        fields = ['name', 'creator', 'questions']

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:15:17