具有自引用对象的 Django Rest 框架嵌套序列化器

5 django django-rest-framework

我已经尝试了其他地方发布的一些针对此问题的解决方案,但没有成功。DRF 似乎本身不支持它。有人对如何实现这一目标有建议吗?

我有一个reports模型和一个section模型。一个节的定义如下:

class Section(models.Model):
    title = models.CharField(max_length=255)
    report = models.ForeignKey(Report)
    order = models.PositiveIntegerField()
    section = models.ForeignKey('self', related_name='section_section', blank=True, null=True)
    content = models.TextField(blank=True)
Run Code Online (Sandbox Code Playgroud)

我想让它在报告下显示这样的数据:

[
    {
        "id": 1,
        "title": "test",
        "subtitle": "test",
        "section_set": [
            {
                "id": 1,
                "title": "test",
                "report": 1,
                "order": 1,
                "section_set": [
                    {
                        "id": 1,
                        "title": "test",
                        "report": 1,
                        "order": 1,
                        "section": null,
                        "content": "<p>test</p>"
                    },
                    {
                        "id": 2,
                        "title": "test",
                        "report": 1,
                        "order": 1,
                        "section": 2,
                        "content": "<p>test</p>"
                    },
                    {
                        "id": 3,
                        "title": "test",
                        "report": 1,
                        "order": 1,
                        "section": null,
                        "content": "<p>test</p>"
                    }
                ],
                "content": "<p>test</p>"
            },
            {
                "id": 2,
                "title": "test",
                "report": 1,
                "order": 1,
                "section": 2,
                "content": "<p>test</p>"
            },
            {
                "id": 3,
                "title": "test",
                "report": 1,
                "order": 1,
                "section": null,
                "content": "<p>test</p>"
            }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

我当前(尝试的)实现如下所示:

class SubsectionSerializer(serializers.ModelSerializer):
class Meta:
    model = Section


class SectionSerializer(serializers.ModelSerializer):
    section = SubsectionSerializer()

    class Meta:
        model = Section
        fields = ('id', 'title', 'report', 'order', 'section', 'content')


class CountryReportSerializer(serializers.ModelSerializer):
    section_set = SectionSerializer(many=True)

    class Meta:
        model = CountryReport
        fields = ('id', 'title', 'subtitle', 'section_set')


class MapsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Map
        fields = ('id', 'country', 'map_image', 'report')
Run Code Online (Sandbox Code Playgroud)

但输出看起来像这样:

{
    "id": 1,
    "title": "test",
    "subtitle": "test",
    "section_set": [
        {
            "id": 1,
            "title": "Section 1",
            "report": 1,
            "order": 1,
            "section": null,
            "content": "<p>test</p>"
        },
        {
            "id": 2,
            "title": "Section 2",
            "report": 1,
            "order": 1,
            "section": null,
            "content": "<p>test</p>"
        },
        {
            "id": 3,
            "title": "Subsection 1",
            "report": 1,
            "order": 1,
            "section": {
                "id": 1,
                "title": "Section 1",
                "order": 1,
                "content": "<p>test</p>",
                "report": 1,
                "section": null
            },
            "content": "<p>test</p>"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*m_O 3

正如错误所示,您定义小节的方式不会将其链接到您的节字段。您是否尝试过像这样定义序列化器:

class SectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Section
Run Code Online (Sandbox Code Playgroud)

因为Section 有一个FK to 部分,所以它应该按照您期望从序列化器返回的方式返回。

为了确保此序列化器返回的 JSON 结果包含嵌套的 JSON 对象,而不仅仅是 FK,您可以采取两种路线:

1)、深度=

class SectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Section
        depth=2
Run Code Online (Sandbox Code Playgroud)

这将沿着 FK 向下,在到达您指定的深度时构建 JSON 对象。

2) 定义一个 SubSerializer 来处理 JSON 对象的创建:

class SubsectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Section

class SectionSerializer(serializers.ModelSerializer):
    section = serializers.SubsectionSerializer()
    class Meta:
        model = Section
        fields = ('id', 'title', 'report', 'order', 'section', 'content')
Run Code Online (Sandbox Code Playgroud)

- - - - - - - - - - - - 编辑 - - - - - - - - - - - - - --

为了清楚起见,重命名模型的相关部分可能是有意义的:

class Section(models.Model):
    title = models.CharField(max_length=255)
    report = models.ForeignKey(Report)
    order = models.PositiveIntegerField()
    parent_section = models.ForeignKey('self', related_name='child_sections', blank=True, null=True)
    content = models.TextField(blank=True)
Run Code Online (Sandbox Code Playgroud)

使用新名称,您应该能够使用以下序列化程序:

class SectionSerializer(serializers.ModelSerializer):
    child_sections = serializers.SubsectionSerializer(many=True)
    class Meta:
        model = Section
        fields = ('id', 'title', 'report', 'order', 'child_sections', 'content')
Run Code Online (Sandbox Code Playgroud)