1

I have a database relationship like the following:

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

I want to nest the serializers for the Child in the Container serializer so I can get both objects in one HTTP request. However, when I query for a list of Containers, Django REST Framework does a single query to get all the Containers, but then does a bunch of individual queries for each set of Child objects associated with a specific Container object. Here is my toy example:

# 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

Is there a way to coalesce all the Child queries into one backend query and then distribute the results amongst the Container objects?

0

1 Answer 1

1

Django REST Framework will not optimize your queries for you, it's up to you to decide how best to remove any N+1 queries. You should follow the guidelines covered in the Django documentation to handle performance issues.

In the case of ForeignKey relationships, you should use select_related in your query, which will pre-fetch the objects in the original query.

In the case of ManyToMany and GenericForeignKey relationships, you should use prefetch_related. I've written quite a bit about this in another Stack Overflow answer, but the gist is that you use it similar to select_related.

You should override the query in get_queryset on the view for best results, as you don't need to worry about Django REST Framework incorrectly cloning the queryset when used as an attribute on the class.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.