我有一个数据库关系,如下所示:
+-----------+
| 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在用作类的属性时会错误地克隆查询集。