✨(backend) add new "descendants" action to document API endpoint
We want to be able to make a search query inside a hierchical document. It's elegant to do it as a document detail action so that we benefit from access control.
This commit is contained in:
committed by
Manuel Raynaud
parent
56aa69f56a
commit
2203d49a52
@@ -177,7 +177,14 @@ class ListDocumentSerializer(serializers.ModelSerializer):
|
||||
request = self.context.get("request")
|
||||
|
||||
if request:
|
||||
return document.get_abilities(request.user)
|
||||
paths_links_mapping = self.context.get("paths_links_mapping", None)
|
||||
# Retrieve ancestor links from paths_links_mapping (if provided)
|
||||
ancestors_links = (
|
||||
paths_links_mapping.get(document.path[: -document.steplen])
|
||||
if paths_links_mapping
|
||||
else None
|
||||
)
|
||||
return document.get_abilities(request.user, ancestors_links=ancestors_links)
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import logging
|
||||
import re
|
||||
import uuid
|
||||
from collections import defaultdict
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from django.conf import settings
|
||||
@@ -21,7 +20,6 @@ from django.http import Http404
|
||||
|
||||
import rest_framework as drf
|
||||
from botocore.exceptions import ClientError
|
||||
from django_filters import rest_framework as drf_filters
|
||||
from rest_framework import filters, status, viewsets
|
||||
from rest_framework import response as drf_response
|
||||
from rest_framework.permissions import AllowAny
|
||||
@@ -424,6 +422,7 @@ class DocumentViewSet(
|
||||
serializer_class = serializers.DocumentSerializer
|
||||
ai_translate_serializer_class = serializers.AITranslateSerializer
|
||||
children_serializer_class = serializers.ListDocumentSerializer
|
||||
descendants_serializer_class = serializers.ListDocumentSerializer
|
||||
list_serializer_class = serializers.ListDocumentSerializer
|
||||
trashbin_serializer_class = serializers.ListDocumentSerializer
|
||||
tree_serializer_class = serializers.ListDocumentSerializer
|
||||
@@ -841,17 +840,24 @@ class DocumentViewSet(
|
||||
else drf.exceptions.NotAuthenticated()
|
||||
)
|
||||
|
||||
ancestors_links_definitions = defaultdict(set)
|
||||
paths_links_mapping = {}
|
||||
ancestors_links = []
|
||||
children_clause = db.Q()
|
||||
for ancestor in ancestors:
|
||||
if ancestor.depth < highest_readable.depth:
|
||||
continue
|
||||
|
||||
ancestors_links_definitions[ancestor.link_reach].add(ancestor.link_role)
|
||||
children_clause |= db.Q(
|
||||
path__startswith=ancestor.path, depth=ancestor.depth + 1
|
||||
)
|
||||
|
||||
# Compute cache for ancestors links to avoid many queries while computing
|
||||
# abilties for his documents in the tree!
|
||||
ancestors_links.append(
|
||||
{"link_reach": ancestor.link_reach, "link_role": ancestor.link_role}
|
||||
)
|
||||
paths_links_mapping[ancestor.path] = ancestors_links.copy()
|
||||
|
||||
children = self.queryset.filter(children_clause, deleted_at__isnull=True)
|
||||
|
||||
queryset = ancestors.filter(depth__gte=highest_readable.depth) | children
|
||||
@@ -866,7 +872,7 @@ class DocumentViewSet(
|
||||
many=True,
|
||||
context={
|
||||
"request": request,
|
||||
"ancestors_links_definitions": ancestors_links_definitions,
|
||||
"paths_links_mapping": paths_links_mapping,
|
||||
},
|
||||
)
|
||||
return drf.response.Response(
|
||||
|
||||
Reference in New Issue
Block a user