【问题标题】:django-restframework serialize relations as dictionaries rather then arraysdjango-rest 框架序列化器关系作为字典而不是数组
【发布时间】:2017-12-27 09:40:56
【问题描述】:

我正在尝试将外键序列化为字典而不是数组。 现在 json 看起来如下:

{
"slug": "en",
"children": [{
        "slug": "pants",
        "children": [{
                "slug": "products/:level1",
                "children": [{
                    "slug": ":level2/:level3",
                    "children": []
                }]
            },
            {
                "slug": ":productSlug",
                "children": []
            }
        ]
    },
    {
        "slug": "pullovers",
        "children": []
    }
   ]
}

但我希望它使用蛞蝓作为钥匙:

{
"en": {
    "children": {
        "pants": {
            "children": {
                "products/:level1": {
                    "children": {
                        ":level2/:level3": {
                            "children": {}
                        }
                    }
                }
            },
            ":productSlug": {
                "children": {}
            }
        ]
    }
 }
}

是否可以直接在序列化程序中执行此操作,还是必须在附加步骤中进行转换?

【问题讨论】:

    标签: python json django django-rest-framework


    【解决方案1】:

    正如我在answer 中所建议的那样,可以通过覆盖list serializers 并为每个需要它的序列化程序设置list_serializer_class 来实现。

    当然,你需要稍微调整一下:

    class <YourClass>ListSerializer(serializers.ListSerializer):
        def to_representation(self, data):
            r = super().to_representation(data)
    
            return { item['<key_field>']: item for item in r }
    

    【讨论】:

    • 不错的答案。我不得不稍微调整一下,所以我也可以将它用于顶级。请看我的回答。
    【解决方案2】:

    @Michael Rigonis 的回答 (https://stackoverflow.com/a/45238191/270265) 是成功的关键。我不得不稍微调整一下,所以我也可以将它用于顶级。:

    class DictSerializer(serializers.ListSerializer):
        key = None
    
        def __init__(self, *args, **kwargs):
            self.key = kwargs.pop('key', self.key)
            super().__init__(*args, **kwargs)
    
        def to_representation(self, data):    
            r = super().to_representation(data)
            return {item[self.key]: item for item in r}
    
        @property
        def data(self):
            # This is a bit nasty, because the only "Many-Serializer" is a ListSerializer we inherit of it,
            # but when converting it to json we call the BaseSerializer directly, because we want a Dictionary rather then a list
            ret = super(serializers.ListSerializer, self).data
            return ReturnDict(ret, serializer=self)
    

    【讨论】:

    • 查看 DRF 代码,似乎确实有必要在 data 中使用 ReturnDict
    猜你喜欢
    • 2017-02-09
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2021-01-11
    • 2020-12-28
    • 2020-03-22
    相关资源
    最近更新 更多