@@ -443,14 +443,15 @@ def filter_queryset(self, queryset):
443
443
queryset = queryset .annotate_user_roles (user )
444
444
return queryset
445
445
446
- def get_response_for_queryset (self , queryset ):
446
+ def get_response_for_queryset (self , queryset , context = None ):
447
447
"""Return paginated response for the queryset if requested."""
448
+ context = context or self .get_serializer_context ()
448
449
page = self .paginate_queryset (queryset )
449
450
if page is not None :
450
- serializer = self .get_serializer (page , many = True )
451
+ serializer = self .get_serializer (page , many = True , context = context )
451
452
return self .get_paginated_response (serializer .data )
452
453
453
- serializer = self .get_serializer (queryset , many = True )
454
+ serializer = self .get_serializer (queryset , many = True , context = context )
454
455
return drf .response .Response (serializer .data )
455
456
456
457
def list (self , request , * args , ** kwargs ):
@@ -460,9 +461,6 @@ def list(self, request, *args, **kwargs):
460
461
This method applies filtering based on request parameters using `ListDocumentFilter`.
461
462
It performs early filtering on model fields, annotates user roles, and removes
462
463
descendant documents to keep only the highest ancestors readable by the current user.
463
-
464
- Additional annotations (e.g., `is_highest_ancestor_for_user`, favorite status) are
465
- applied before ordering and returning the response.
466
464
"""
467
465
user = self .request .user
468
466
@@ -490,12 +488,6 @@ def list(self, request, *args, **kwargs):
490
488
)
491
489
queryset = queryset .filter (path__in = root_paths )
492
490
493
- # Annotate the queryset with an attribute marking instances as highest ancestor
494
- # in order to save some time while computing abilities on the instance
495
- queryset = queryset .annotate (
496
- is_highest_ancestor_for_user = db .Value (True , output_field = db .BooleanField ())
497
- )
498
-
499
491
# Annotate favorite status and filter if applicable as late as possible
500
492
queryset = queryset .annotate_is_favorite (user )
501
493
queryset = filterset .filters ["is_favorite" ].filter (
@@ -827,7 +819,17 @@ def children(self, request, *args, **kwargs):
827
819
828
820
queryset = filterset .qs
829
821
830
- return self .get_response_for_queryset (queryset )
822
+ # Pass ancestors' links paths mapping to the serializer as a context variable
823
+ # in order to allow saving time while computing abilities on the instance
824
+ paths_links_mapping = document .compute_ancestors_links_paths_mapping ()
825
+
826
+ return self .get_response_for_queryset (
827
+ queryset ,
828
+ context = {
829
+ "request" : request ,
830
+ "paths_links_mapping" : paths_links_mapping ,
831
+ },
832
+ )
831
833
832
834
@drf .decorators .action (
833
835
detail = True ,
@@ -886,39 +888,28 @@ def tree(self, request, pk, *args, **kwargs):
886
888
ancestors_links = []
887
889
children_clause = db .Q ()
888
890
for ancestor in ancestors :
889
- if ancestor .depth < highest_readable .depth :
890
- continue
891
-
892
- children_clause |= db .Q (
893
- path__startswith = ancestor .path , depth = ancestor .depth + 1
894
- )
895
-
896
891
# Compute cache for ancestors links to avoid many queries while computing
897
892
# abilities for his documents in the tree!
898
893
ancestors_links .append (
899
894
{"link_reach" : ancestor .link_reach , "link_role" : ancestor .link_role }
900
895
)
901
896
paths_links_mapping [ancestor .path ] = ancestors_links .copy ()
902
897
898
+ if ancestor .depth < highest_readable .depth :
899
+ continue
900
+
901
+ children_clause |= db .Q (
902
+ path__startswith = ancestor .path , depth = ancestor .depth + 1
903
+ )
904
+
903
905
children = self .queryset .filter (children_clause , deleted_at__isnull = True )
904
906
905
907
queryset = ancestors .filter (depth__gte = highest_readable .depth ) | children
906
908
queryset = queryset .order_by ("path" )
907
- # Annotate if the current document is the highest ancestor for the user
908
- queryset = queryset .annotate (
909
- is_highest_ancestor_for_user = db .Case (
910
- db .When (
911
- path = db .Value (highest_readable .path ),
912
- then = db .Value (True ),
913
- ),
914
- default = db .Value (False ),
915
- output_field = db .BooleanField (),
916
- )
917
- )
918
909
queryset = queryset .annotate_user_roles (user )
919
910
queryset = queryset .annotate_is_favorite (user )
920
911
921
- # Pass ancestors' links definitions to the serializer as a context variable
912
+ # Pass ancestors' links paths mapping to the serializer as a context variable
922
913
# in order to allow saving time while computing abilities on the instance
923
914
serializer = self .get_serializer (
924
915
queryset ,
@@ -1520,8 +1511,8 @@ def list(self, request, *args, **kwargs):
1520
1511
except models .Document .DoesNotExist :
1521
1512
return drf .response .Response ([])
1522
1513
1523
- roles = set ( document .get_roles (user ) )
1524
- if not roles :
1514
+ role = document .get_role (user )
1515
+ if role is None :
1525
1516
return drf .response .Response ([])
1526
1517
1527
1518
ancestors = (
@@ -1539,7 +1530,7 @@ def list(self, request, *args, **kwargs):
1539
1530
document__in = ancestors .filter (depth__gte = highest_readable .depth )
1540
1531
)
1541
1532
1542
- is_privileged = bool ( roles . intersection ( set ( choices .PRIVILEGED_ROLES )))
1533
+ is_privileged = role in choices .PRIVILEGED_ROLES
1543
1534
if is_privileged :
1544
1535
serializer_class = serializers .DocumentAccessSerializer
1545
1536
else :
0 commit comments