️(backend) optimize number of queries on document list view

I realized most of the database queries made when getting a document
list view were to include nested accesses. This detailed information
about accesses in only necessary for the document detail view.

I introduced a specific serializer for the document list view with
less fields. For a list of 20 documents with 5 accesses, we go down
from 3x5x20= 300 queries to just 3 queries.
This commit is contained in:
Samuel Paccoud - DINUM
2024-11-09 10:27:21 +01:00
committed by Anthony LC
parent 797d9442ac
commit 2c915d53f4
6 changed files with 97 additions and 262 deletions

View File

@@ -137,32 +137,55 @@ class BaseResourceSerializer(serializers.ModelSerializer):
return {}
class DocumentSerializer(BaseResourceSerializer):
"""Serialize documents."""
class ListDocumentSerializer(BaseResourceSerializer):
"""Serialize documents with limited fields for display in lists."""
content = serializers.CharField(required=False)
accesses = DocumentAccessSerializer(many=True, read_only=True)
class Meta:
model = models.Document
fields = [
"id",
"content",
"title",
"accesses",
"abilities",
"content",
"created_at",
"link_role",
"link_reach",
"created_at",
"title",
"updated_at",
]
read_only_fields = [
"id",
"accesses",
"abilities",
"created_at",
"link_role",
"link_reach",
"updated_at",
]
class DocumentSerializer(ListDocumentSerializer):
"""Serialize documents with all fields for display in detail views."""
content = serializers.CharField(required=False)
class Meta:
model = models.Document
fields = [
"id",
"abilities",
"content",
"created_at",
"link_role",
"link_reach",
"title",
"updated_at",
]
read_only_fields = [
"id",
"abilities",
"created_at",
"link_role",
"link_reach",
"updated_at",
]

View File

@@ -346,15 +346,23 @@ class DocumentViewSet(
):
"""Document ViewSet"""
access_model_class = models.DocumentAccess
metadata_class = DocumentMetadata
ordering = ["-updated_at"]
permission_classes = [
permissions.AccessPermission,
]
serializer_class = serializers.DocumentSerializer
access_model_class = models.DocumentAccess
resource_field_name = "document"
queryset = models.Document.objects.all()
ordering = ["-updated_at"]
metadata_class = DocumentMetadata
resource_field_name = "document"
serializer_class = serializers.DocumentSerializer
def get_serializer_class(self):
"""
Use ListDocumentSerializer for list actions, otherwise use DocumentSerializer.
"""
if self.action == "list":
return serializers.ListDocumentSerializer
return self.serializer_class
def list(self, request, *args, **kwargs):
"""Restrict resources returned by the list endpoint"""