如何在django-rest框架中使用嵌套的序列化程序组合小型查询



我有一个数据库关系,如下所示:

  +-----------+
  | Container |
  +-----------+
  | id        |
  +-----------+
        | 
        |1..n 
+--------------+
| Child        |
+--------------+
| id           |
| container_id |
+--------------+

我想在Container序列化程序中嵌套Child的序列化程序,这样我就可以在一个HTTP请求中获得这两个对象。然而,当我查询Containers的列表时,Django REST框架只执行一个查询来获得所有的Containers,然后对与特定Container对象关联的每组Child对象执行一组单独的查询。这是我的玩具示例:

# Models
class Container(models.Model):
    pass
class Child(models.Model):
    container = models.ForeignKey(Container,related_name="children")
# Serializers
class ChildSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Child
        fields = ('url','container')
class ContainerSerializer(serializers.HyperlinkedModelSerializer):
    children = ChildSerializer(many=True)
    class Meta:
        model = Container
        fields = ('url','children')
# Views
class ContainerViewSet(viewsets.ModelViewSet)
    queryset = Container.objects.all()
    serializer_class = ContainerSerializer
class ChildViewSet(viewsets.ModelViewSet)
    queryset = Child.objects.all()
    serializer_class = ChildSerializer

有没有一种方法可以将所有Child查询合并为一个后端查询,然后在Container对象之间分配结果?

Django REST框架不会为您优化查询,而是由您决定如何最好地删除任何N+1查询。您应该遵循Django文档中包含的准则来处理性能问题。

在ForeignKey关系的情况下,您应该在查询中使用select_related,它将预取原始查询中的对象。

在ManyToMany和GenericForeignKey关系的情况下,应该使用prefetch_related。我在另一个Stack Overflow答案中已经写了很多关于这一点的内容,但要点是您使用它类似于select_related

为了获得最佳结果,您应该覆盖视图上get_queryset中的查询,因为您不需要担心Django REST Framework在用作类的属性时会错误地克隆查询集。

相关内容

最新更新