Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python DRF:用于相关模型的异构列表的序列化程序_Python_Django_Serialization_Orm_Django Rest Framework - Fatal编程技术网

Python DRF:用于相关模型的异构列表的序列化程序

Python DRF:用于相关模型的异构列表的序列化程序,python,django,serialization,orm,django-rest-framework,Python,Django,Serialization,Orm,Django Rest Framework,粗略地说,我在ORM中有以下模式: class Page(models.Model): title = models.CharField(max_length=255, null=False, blank=False) @property def content(self): return [Video.objects.all()[0], Text.objects.all()[0], Video.objects.all()[1]] 我有以下一组类来支

粗略地说,我在ORM中有以下模式:

class Page(models.Model):

    title = models.CharField(max_length=255, null=False, blank=False)

    @property
    def content(self):
        return [Video.objects.all()[0], Text.objects.all()[0], Video.objects.all()[1]]
我有以下一组类来支持详细视图的序列化:

class ContentSerializer(serializers.ListSerializer):

    class Meta:
        model = ???
        fields = '???'


class PageDetailSerializer(serializers.ModelSerializer):
    content = ContentSerializer(many=True)

    class Meta:
        model = Page
        fields = ('title', 'content', )
因此,我正在寻找一种序列化
Page.content
属性的方法,即:

  • 名单
  • 将包含异构数据(例如,
    视频
    音频
    文本
    和其他模型的组合)
  • 因此,我需要以某种方式修补一个内置序列化程序,以遍历列表并检查每个对象的类型。然后决定如何序列化每个对象。例如,我可以准备一种动态创建的
    ModelSerializer

    obj_type = type(obj)
    
    class ContentModelSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = obj_type
            fields = '__all__'
    
    serialized_obj = ContentModelSerializer(obj)
    

    我如何实现这一点?

    您可以通过覆盖
    页面
    序列化程序的
    to_表示
    方法来实现这一点。如下所示:

    class PageDetailSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Page
        fields = ('title', 'content', )
    
    def to_representation(self, instance):
        ctx = super(PageDetailSerializer, self).to_representation(instance)
        content = instance.content         # property field of page, will return list of items
        serialized_content = []
        for c in content:
            if type(c) == Video:
                serialized_content.append({... serialized data of video type ..})
            elif type(c) == ...
                # other conditions here..
    

    在找到解决方案之前,我在谷歌上搜索了很多。它引用了
    SerializerMethodField
    ,允许您为字段添加自定义处理程序。最后一个对我有效的解决方案是:

    class PageDetailSerializer(serializers.ModelSerializer):
    _缓存_序列化程序={}
    content=serializers.SerializerMethodField()
    类元:
    型号=页
    字段=('title','content',)
    def_get_content_item_序列化程序(self,content_item_type):
    如果内容\项\类型不在self.\缓存\序列化程序中:
    类ContentItemSerializer(serializers.ModelSerializer):
    类元:
    模型=内容\项目\类型
    排除=('id','page',)
    self.\u缓存\u序列化程序[内容\u项目\u类型]=内容项目序列化程序
    返回self.\u缓存\u序列化程序[内容\u项\u类型]
    def get_内容(自身、页面):
    返回[
    self.\u get\u content\u item\u序列化程序(类型(content\u item))(content\u item)。page.content中content\u item的数据
    ]
    
    我想使用SerializerMethodField谢谢你的建议!我发现SerializerMethodField适合我的需要。