使用 Django REST 框架从多个模型返回结果

Posted

技术标签:

【中文标题】使用 Django REST 框架从多个模型返回结果【英文标题】:Return results from multiple models with Django REST Framework 【发布时间】:2013-09-13 04:22:18 【问题描述】:

我有三个模型——文章、作者和推文。我最终需要使用 Django REST 框架来构建一个提要,该提要将使用文章和推文模型的所有对象聚合到一个逆时间顺序提要中。

知道我会怎么做吗?我觉得我需要创建一个新的序列化程序,但我真的不确定。

谢谢!

编辑:这是我迄今为止所做的。

app/serializers.py:

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

app/views.py:

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

【问题讨论】:

你的问题是如何合并不同物体的两条时间线,还是如何使用DRF输出已经合并的时间线? 在某种程度上可能两者兼而有之('害怕我有点像 Django 新手......)。我将在一分钟内更新代码,但我目前创建了一个新视图,它使用itertools.chain() 创建一个结合Tweet.objects.all()Article.objects.all() 的查询集,并将其提供给一个新的序列化程序,其中列出了两个模型共有的字段。我在正确的道路上附近吗? 你可以使用这个 - github.com/Axiologue/DjangoRestMultipleModels. 【参考方案1】:

它看起来离我很近。我个人没有在 DRF 中使用过 ViewSets,但我认为如果您将代码更改为此,您应该会有所收获(抱歉 - 没有测试过这两个):

class TimelineViewSet(viewsets.ModelViewSet):
    """
    API endpoint that lists all tweet/article objects in rev-chrono.
    """
    def list(self, request):
        queryset = list(itertools.chain(Tweet.objects.all(), Article.objects.all()))
        serializer = TimelineSerializer(queryset, many=True)
        return Response(serializer.data)

如果您不喜欢使用 ViewSet,那么 generics.ListAPIView 会更简单一些:

class TimeLineList(generics.ListAPIView):
    serializer_class = TimeLineSerializer

    def get_queryset(self):
        return list(itertools.chain(Tweet.objects.all(), Article.objects.all()))

请注意,您必须将 chain 的输出转换为列表才能正常工作。

【讨论】:

我尝试了第二条路线,并收到以下错误:“base_name 未指定参数,并且无法从视图集中自动确定名称,因为它没有 .model.queryset 属性。”如果我用queryset = list(itertools.chain(Tweet.objects.all(), Article.objects.all())) 替换“get_queryset”节,什么都不会发生,整个事情都会挂起。知道我可能做错了什么吗? 哇,第一个变种完全可以工作了。发现此问题的任何人的附加说明:1.您需要在views.py 中的from rest_framework.response import Response。 2. 在site/urls.py注册路由器时,需要指定base_name,如下:router.register(r'timeline', views.TimelineViewSet, 'timeline') 另一个注意事项 - 序列化程序中使用的字段必须存在于两个模型中提供给itertools.chain(),仅仅为序列化程序中的唯一字段设置“required=False”不会做任何事情。 理想情况下,您应该将评论作为答案发布或将编辑添加到问题中,以便对其他人有所帮助

以上是关于使用 Django REST 框架从多个模型返回结果的主要内容,如果未能解决你的问题,请参考以下文章

序列化多个模型并在一个 json 响应中发送全部 django rest 框架

Django:从 Pandas 到 Django Rest 框架的模型查询集

如何使用 django rest 框架从 GET 请求的查询参数中过滤多个 id?

Django REST框架 - 多个查找字段?

django rest框架返回视图中的选定字段

如何在 Django REST 框架中使用事务?