django rest框架json序列化器

Posted

技术标签:

【中文标题】django rest框架json序列化器【英文标题】:django rest framework json serializer 【发布时间】:2015-10-29 10:31:17 【问题描述】:

我想要来自 Django REST 框架的 json 响应,所以我有这样的 Json 响应:.

[
    
        "id": 1,
        "TitleEnglish": "Tiny Talents Program",
        "TitleArabic": "Tiny Talents Program",
        "DescriptionEnglish": "Timing: 8:00 am till 1:00 pm",
        "DescriptionArabic": "Timing: 8:00 am till 1:00 pm",
        "CategoryEnglish": "Art & Education ",
        "CategoryArabic": "Art & Education ",
        "Date": "2015-05-07",
        "Status": true,
        "Image": "--"
    
]

但我需要这样的回应:


"data": [
    
        "id": 1,
        "TitleEnglish": "Tiny Talents Program",
        "TitleArabic": "Tiny Talents Program",
        "DescriptionEnglish": "Timing: 8:00 am till 1:00 pm",
        "DescriptionArabic": "Timing: 8:00 am till 1:00 pm",
        "CategoryEnglish": "Art & Education ",
        "CategoryArabic": "Art & Education ",
        "Date": "2015-05-07",
        "Status": true,
        "Image": "--"
    
       ]

我的序列化代码是:

class PromotionSerializer(serializers.HyperlinkedModelSerializer):
    CategoryEnglish  = serializers.CharField(read_only=True, source="Category.TitleEnglish")
    CategoryArabic  = serializers.CharField(read_only=True, source="Category.TitleArabic")
    class Meta:
        model = Promotion
        fields = ('id', 'TitleEnglish', 'TitleArabic', 'DescriptionEnglish', 'DescriptionArabic', 'CategoryEnglish','CategoryArabic', 'Date','Status','Image')

【问题讨论】:

您需要创建一个自定义渲染器。 django-rest-framework.org/api-guide/renderers/#custom-renderers这个我没试过,但我相信它适合你的问题 【参考方案1】:

我通过更改视图解决了我的问题:

我添加了一个列表方法,我的问题解决了:

def list(self, request):
    queryset = Promotion.objects.all()
    serializer_class = PromotionSerializer(queryset, many=True)
    serialized_data =  'data': serializer_class.data
    return Response(serialized_data)

【讨论】:

太棒了!我也在做同样的事情,并通过在序列化程序的Meta 类中定义一个list_serializer_class 来完成。将更新我以前的答案。 这是用更少的代码和更少的覆盖来解决问题的另一种选择! +1【参考方案2】:

我认为您可以通过自定义 ListSerializer 行为来做到这一点,该行为在为 list 请求创建序列化响应时使用。

我们可以创建一个自定义的PromotionListSerializer,当使用many=Tue 参数将多个实例传递给序列化程序进行序列化时将使用它。

我们覆盖 PromotionListSerializer 类中的 data 属性以返回我们的自定义表示。

class PromotionListSerializer(serializers.ListSerializer):

    @property
    def data(self):
        # call the super() to get the default serialized data
        serialized_data =  super(PromotionListSerializer, self).data       
        custom_representation = 'data': serialized_data # insert the above response in a dictionary
        return custom_representation

然后在您的PromotionSerializer 中,在Meta 中指定此自定义列表序列化程序类。然后在序列化多个实例时将使用此自定义列表序列化程序类。

class PromotionSerializer(serializers.HyperlinkedModelSerializer):
    CategoryEnglish  = serializers.CharField(read_only=True, source="Category.TitleEnglish")
    CategoryArabic  = serializers.CharField(read_only=True, source="Category.TitleArabic")
    class Meta:
        model = Promotion
        fields = ('id', 'TitleEnglish', 'TitleArabic', 'DescriptionEnglish', 'DescriptionArabic', 'CategoryEnglish','CategoryArabic', 'Date','Status','Image')

        # define the custome list serializer class to be used
        list_serializer_class = PromotionListSerializer

解决方案 2:

覆盖视图的list 方法并返回自定义表示,而不是您在your ans. 中提到的默认响应

扩展OP's 答案,这也将为分页响应提供支持。这是 DRF 中的实际代码,我刚刚返回了 custom_representation 而不是最后的 serializer.data

def list(self, request, *args, **kwargs):
    instance = self.filter_queryset(self.get_queryset())
    page = self.paginate_queryset(instance)
    if page is not None:
        serializer = self.get_pagination_serializer(page)
    else:
        serializer = self.get_serializer(instance, many=True)
    serialized_data = serializer.data
    custom_representation = 'data': serialized_data
    return Response(custom_representation)

【讨论】:

还有问题[ "data": "id": 1, "TitleEnglish": "Tiny Talents Program", "TitleArabic": "Tiny Talents Program", "DescriptionEnglish": "Timing: 8:00 am till 1:00 pm", "DescriptionArabic": "Timing: 8:00 am till 1:00 pm", "CategoryEnglish": "Art & Education ", "CategoryArabic": "Art & Education ", "Date": "2015-05-07", "Status": true, "Image": "--" ] 我想删除起始数组并从字典开始,然后以我的问题格式查看数据数组。谢谢你的帮助:) 更新了答案。实际上,在 list 请求的情况下,即当多个实例被序列化时,仅覆盖 to_representation 将不起作用。在调用to_represention 之后,DRF 在.data 属性中使用ReturnList 类,这再次给了我一个列表。我可以通过创建自定义列表序列化程序类并覆盖 data 属性来解决问题,以便它返回我的自定义表示。 您在ans中给出的方法对于解决问题也是正确的。我稍微扩展了您的解决方案。请检查。 :) 谢谢,它也会解决我的问题,但我已经解决了:)【参考方案3】:

最简单的解决方案是覆盖 to_representation 方法

def to_representation(self, instance):
    data = super(PromotionSerializer, self).to_representation(instance)
    return 'data': data 

【讨论】:

这很优雅!

以上是关于django rest框架json序列化器的主要内容,如果未能解决你的问题,请参考以下文章

Django rest_framewok框架的基本组件

django rest框架嵌套模型序列化器

Django Haystack 结果到 Django Rest 框架序列化器

django double left join + django rest 框架序列化器

如何使用 Django REST 序列化器?

django REST framework 嵌套序列化器和 POST 嵌套 JSON 文件