序列化多个模型并在一个json响应中发送所有jjango rest框架

时间:2017-07-07 19:05:52

标签: python json django rest django-rest-framework

这个问题被要求扩展并填补这个漏洞:Return results from multiple models with Django REST Framework

我的目标是返回一个json对象,我将使用它来动态填充html代码中各种select语句中的选项。

所以我想从模型a中获取一个属性,另一个来自模型b等

然后我想要属性a和b以及c等的所有值

作为键的json数组的值,所以

json ={

modelA: {'atter1, atter2, atter3}
modelB: {'atter1, atter2, atter3}
model..:{you get the point}
}

上面引用的帖子中的这部分是有道理的:

class TimelineViewSet(viewsets.ModelViewSet):
    """
    API endpoint that lists all tweet/article objects in rev-chrono.
    """
    queryset = itertools.chain(Tweet.objects.all(), Article.objects.all())
    serializer_class = TimelineSerializer

这不是什么:

class TimelineSerializer(serializers.Serializer):
    pk = serializers.Field()
    title = serializers.CharField()
    author = serializers.RelatedField()
    pub_date = serializers.DateTimeField()

如何将单独的模型属性设置为正确的json键?

我假设它类似于序列化器关系,但这些值通过onetoone,onetomany或许多对多来不相关。我只想一次获取所有这些信息,而不是为每个值创建一个api。

我是一个迷失的小女孩,我要求你帮我找回家的路。拥抱和亲吻。

2 个答案:

答案 0 :(得分:17)

如果你理性地设计你的响应格式,你会在Django REST Framework中找到更容易的东西。

目前看起来有点模糊,但我建议如下:

{
    "tweets": [
        {"tweet_attr_A": value_1, ...},  // first tweet
        {"tweet_attr_A": value_2, ...},  // second tweet
        //etc
    ],
    "articles": [
        {"id": 1, ...},  // first article
        {"id": 2, ...},  // second article
        //etc
    ]
}

我们可以使用三个序列化程序来表达这一点,例如:

class TweetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tweet

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article

class TimelineSerializer(serializers.Serializer):
    tweets = TweetSerializer(many=True)
    articles = ArticleSerializer(many=True)

http://www.django-rest-framework.org/api-guide/serializers/#dealing-with-nested-objects

然后,因为我们使用的是多个模型,所以最简单的方法就是定义自己的自定义视图集,而不是试图将其变成DRF神奇的ModelViewSet类型。
http://www.django-rest-framework.org/api-guide/viewsets/#example

首先,我们需要一个对象类型传递到我们的TimelineSerializer,它有两个属性:tweetsarticles

from collections import namedtuple

Timeline = namedtuple('Timeline', ('tweets', 'articles'))

然后我们将定义自定义视图集以获取推文和文章,实例化时间轴对象并返回TimelineSerializer数据:

class TimelineViewSet(viewsets.ViewSet):
    """
    A simple ViewSet for listing the Tweets and Articles in your Timeline.
    """
    def list(self, request):
        timeline = Timeline(
            tweets=Tweet.objects.all(),
            articles=Article.objects.all(),
        )
        serializer = TimelineSerializer(timeline)
        return Response(serializer.data)

答案 1 :(得分:1)

我遇到相同的情况,要序列化多个模型以从每个序列化模型中获取过滤后的输出,以从一个api中使用。我碰到了this module以达到这个结果。