Django select_related() not reducing database queries in a nested serializer

 

I’m working on a Django REST Framework API where I need to return a list of projects along with their assigned employees and each employee’s department.

The models are structured roughly like this:

class Department(models.Model):
    name = models.CharField(max_length=100)


class Employee(models.Model):
    name = models.CharField(max_length=100)
    department = models.ForeignKey(Department, on_delete=models.CASCADE)


class Project(models.Model):
    name = models.CharField(max_length=100)
    employees = models.ManyToManyField(Employee)

My serializer is:

class EmployeeSerializer(serializers.ModelSerializer):
    department = serializers.CharField(source="department.name")

    class Meta:
        model = Employee
        fields = ["id", "name", "department"]


class ProjectSerializer(serializers.ModelSerializer):
    employees = EmployeeSerializer(many=True)

    class Meta:
        model = Project
        fields = ["id", "name", "employees"]

Initially, I used:

projects = Project.objects.all()

This resulted in a large number of database queries because each project loads its employees separately, and each employee loads its department separately.

I tried optimizing it with:

projects = Project.objects.prefetch_related(
    "employees__department"
)

However, when I inspect the queries using Django Debug Toolbar, I still see more queries than expected.

I expected the queryset to execute only a small number of queries regardless of how many projects and employees are returned.

What is the correct way to optimize this queryset for the nested serializer? Is prefetch_related("employees__department") sufficient, or should I use Prefetch() with a customized queryset?

0

1

1

No Comment

Be the first to comment

Please sign in join the conversation