(backend) add creator field on document and allow filtering on it

We want to be able to limit the documents displayed on a logged-in user's
list view by the documents they created or by the documents that other
users created.

This is different from having the "owner" role on a document because this
can be acquired and even lost. What we want here is to be able to
identify documents by the user who created them so we add a new field.
This commit is contained in:
Samuel Paccoud - DINUM
2024-11-12 16:28:34 +01:00
committed by Anthony LC
parent 1899cff572
commit 23f90156bf
13 changed files with 453 additions and 68 deletions

View File

@@ -0,0 +1,63 @@
"""API filters for Impress' core application."""
from django.utils.translation import gettext_lazy as _
import django_filters
from core import models
class DocumentFilter(django_filters.FilterSet):
"""
Custom filter for filtering documents.
"""
is_creator_me = django_filters.BooleanFilter(
method="filter_is_creator_me", label=_("Creator is me")
)
class Meta:
model = models.Document
fields = ["is_creator_me"]
# pylint: disable=unused-argument
def filter_is_creator_me(self, queryset, name, value):
"""
Filter documents based on the `creator` being the current user.
Example:
- /api/v1.0/documents/?is_creator_me=true
→ Filters documents created by the logged-in user
- /api/v1.0/documents/?is_creator_me=false
→ Filters documents created by other users
"""
user = self.request.user
if not user.is_authenticated:
return queryset
if value:
return queryset.filter(creator=user)
return queryset.exclude(creator=user)
# pylint: disable=unused-argument
def filter_is_favorite(self, queryset, name, value):
"""
Filter documents based on whether they are marked as favorite by the current user.
Example:
- /api/v1.0/documents/?favorite=true
→ Filters documents marked as favorite by the logged-in user
- /api/v1.0/documents/?favorite=false
→ Filters documents not marked as favorite by the logged-in user
"""
user = self.request.user
if not user.is_authenticated:
return queryset
clause = "filter" if value else "exclude"
return getattr(queryset, clause)(
favorited_by_users__user=user, favorited_by_users__is_favorite=True
)

View File

@@ -150,6 +150,7 @@ class ListDocumentSerializer(BaseResourceSerializer):
"abilities",
"content",
"created_at",
"creator",
"is_favorite",
"link_role",
"link_reach",
@@ -161,6 +162,7 @@ class ListDocumentSerializer(BaseResourceSerializer):
"id",
"abilities",
"created_at",
"creator",
"is_favorite",
"link_role",
"link_reach",
@@ -181,6 +183,7 @@ class DocumentSerializer(ListDocumentSerializer):
"abilities",
"content",
"created_at",
"creator",
"is_favorite",
"link_role",
"link_reach",
@@ -192,6 +195,7 @@ class DocumentSerializer(ListDocumentSerializer):
"id",
"abilities",
"created_at",
"creator",
"is_avorite",
"link_role",
"link_reach",

View File

@@ -22,10 +22,10 @@ from django.db.models import (
from django.http import Http404
from botocore.exceptions import ClientError
from django_filters import rest_framework as filters
from rest_framework import (
decorators,
exceptions,
filters,
metadata,
mixins,
pagination,
@@ -33,6 +33,9 @@ from rest_framework import (
views,
viewsets,
)
from rest_framework import (
filters as drf_filters,
)
from rest_framework import (
response as drf_response,
)
@@ -42,6 +45,7 @@ from core import enums, models
from core.services.ai_services import AIService
from . import permissions, serializers, utils
from .filters import DocumentFilter
ATTACHMENTS_FOLDER = "attachments"
UUID_REGEX = (
@@ -311,9 +315,23 @@ class DocumentViewSet(
mixins.UpdateModelMixin,
viewsets.GenericViewSet,
):
"""Document ViewSet"""
"""
Document ViewSet for managing documents.
filter_backends = [filters.OrderingFilter]
Provides endpoints for creating, updating, and deleting documents,
along with filtering options.
Filtering:
- `is_creator_me=true`: Returns documents created by the current user.
- `is_creator_me=false`: Returns documents created by other users.
Example Usage:
- GET /api/v1.0/documents/?creator=me
- GET /api/v1.0/documents/?creator=other
"""
filter_backends = [filters.DjangoFilterBackend, drf_filters.OrderingFilter]
filterset_class = DocumentFilter
metadata_class = DocumentMetadata
ordering = ["-updated_at"]
ordering_fields = ["created_at", "is_favorite", "updated_at", "title"]
@@ -410,8 +428,8 @@ class DocumentViewSet(
return drf_response.Response(serializer.data)
def perform_create(self, serializer):
"""Set the current user as owner of the newly created object."""
obj = serializer.save()
"""Set the current user as creator and owner of the newly created object."""
obj = serializer.save(creator=self.request.user)
models.DocumentAccess.objects.create(
document=obj,
user=self.request.user,
@@ -739,7 +757,7 @@ class TemplateViewSet(
):
"""Template ViewSet"""
filter_backends = [filters.OrderingFilter]
filter_backends = [drf_filters.OrderingFilter]
permission_classes = [
permissions.IsAuthenticatedOrSafe,
permissions.AccessPermission,