Skip to content
Snippets Groups Projects

Remove EntityRole and EntityLink models

Merged ml bonhomme requested to merge no-entity-role-link into master
26 files
+ 878
1913
Compare changes
  • Side-by-side
  • Inline
Files
26
@@ -3,32 +3,18 @@ from textwrap import dedent
from uuid import UUID
from django.core.exceptions import ValidationError as DjangoValidationError
from django.db.models import Q
from django.shortcuts import get_object_or_404
from drf_spectacular.utils import OpenApiExample, OpenApiParameter, OpenApiResponse, extend_schema, extend_schema_view
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema, extend_schema_view
from rest_framework import permissions, serializers, status
from rest_framework.exceptions import NotFound, PermissionDenied, ValidationError
from rest_framework.generics import CreateAPIView, ListAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView
from rest_framework.generics import CreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView
from rest_framework.response import Response
from arkindex.documents.models import (
Corpus,
Element,
Entity,
EntityLink,
EntityRole,
EntityType,
Transcription,
TranscriptionEntity,
)
from arkindex.documents.models import Corpus, Element, Entity, EntityType, Transcription, TranscriptionEntity
from arkindex.documents.serializers.elements import ElementTinySerializer
from arkindex.documents.serializers.entities import (
BaseEntitySerializer,
CreateEntityRoleErrorResponseSerializer,
EntityCreateSerializer,
EntityLinkCreateSerializer,
EntityLinkSerializer,
EntityRoleSerializer,
EntitySerializer,
EntityTypeCreateSerializer,
EntityTypeSerializer,
@@ -44,53 +30,6 @@ from arkindex.project.permissions import IsVerified, IsVerifiedOrReadOnly
from arkindex.users.models import Role
@extend_schema(tags=["entities"])
@extend_schema_view(
get=extend_schema(operation_id="ListCorpusRoles", description="List all roles of a corpus"),
post=extend_schema(
description="Create a new entity role",
responses={
200: EntityRoleSerializer,
400: CreateEntityRoleErrorResponseSerializer
},
examples=[OpenApiExample(
status_codes=["400"],
response_only=True,
name="role-exists",
value={"id": "55cd009d-cd4b-4ec2-a475-b060f98f9138", "corpus": ["Role already exists in this corpus"]},
description="Role already exists."
)]
)
)
class CorpusRoles(CorpusACLMixin, ListCreateAPIView):
"""
List all roles in a corpus
"""
permission_classes = (IsVerifiedOrReadOnly, )
serializer_class = EntityRoleSerializer
queryset = EntityRole.objects.none()
def get_queryset(self):
return EntityRole.objects \
.filter(corpus=self.get_corpus(self.kwargs["pk"])) \
.order_by("parent_name", "child_name")
def perform_create(self, serializer):
data = self.request.data
if EntityRole.objects.filter(
parent_name=data["parent_name"],
child_name=data["child_name"],
parent_type=data["parent_type_id"],
child_type=data["child_type_id"],
corpus_id=self.request.parser_context["kwargs"]["pk"]
).exists():
raise serializers.ValidationError({
"corpus": ["Role already exists in this corpus"],
"id": self.request.parser_context["kwargs"]["pk"]
})
super().perform_create(serializer)
@extend_schema(tags=["entities"])
@extend_schema_view(
get=extend_schema(operation_id="ListCorpusEntityTypes", description="List all entity types in a corpus"),
@@ -173,8 +112,6 @@ class EntityTypeUpdate(ACLMixin, RetrieveUpdateDestroyAPIView):
def perform_destroy(self, instance):
if instance.entities.exists():
raise ValidationError({"detail": ["Some entities are using this entity type."]})
if EntityRole.objects.filter(Q(parent_type_id=instance.id) | Q(child_type_id=instance.id)).exists():
raise ValidationError({"detail": ["Some entity roles are using this entity type."]})
super().perform_destroy(instance)
@@ -196,14 +133,6 @@ class EntityDetails(ACLMixin, RetrieveUpdateDestroyAPIView):
.select_related("corpus", "type") \
.filter(corpus__in=Corpus.objects.readable(self.request.user)) \
.prefetch_related(
"parents__role__parent_type",
"parents__role__child_type",
"children__role__parent_type",
"children__role__child_type",
"parents__child__type",
"parents__parent__type",
"children__parent__type",
"children__child__type",
"corpus",
)
@@ -307,15 +236,6 @@ class EntityCreate(CreateAPIView):
return Response(entity.data, status=status_code, headers=headers)
@extend_schema_view(post=extend_schema(operation_id="CreateEntityLink", tags=["entities"]))
class EntityLinkCreate(CreateAPIView):
"""
Create a new link between two entities with a role
"""
permission_classes = (IsVerified, )
serializer_class = EntityLinkCreateSerializer
@extend_schema_view(post=extend_schema(
operation_id="CreateTranscriptionEntity",
tags=["entities"],
@@ -519,41 +439,6 @@ class CorpusEntities(CorpusACLMixin, ListAPIView):
return queryset
@extend_schema_view(get=extend_schema(operation_id="ListElementLinks", tags=["entities"]))
class ElementLinks(CorpusACLMixin, ListAPIView):
"""
List all links where parent and child are linked to the element.\n\n
Requires a **guest** access to the element corpus
"""
serializer_class = EntityLinkSerializer
def get_queryset(self):
try:
element = Element.objects.select_related("corpus").only("id", "corpus").get(id=self.kwargs["pk"])
except Element.DoesNotExist:
raise NotFound
if not self.has_read_access(element.corpus):
raise PermissionDenied(detail="You do not have access to this element.")
# Load entities linked by transcriptions
entities_tr = Entity.objects.filter(transcriptions__element_id=element.id).prefetch_related("transcriptions")
# Load entities linked by metadatas
entities_meta = Entity.objects.filter(metadatas__element_id=element.id).prefetch_related("metadatas")
# Now load all links belonging to those entities
# It's several times faster to combine the queries in the final one
# than combining them at the lower level (entities is slower than entities_tr + entities_meta)
# We need to support cross references between transcriptions & metadata entities
return EntityLink.objects.filter(
Q(parent__in=entities_tr, child__in=entities_tr)
| Q(parent__in=entities_tr, child__in=entities_meta)
| Q(parent__in=entities_meta, child__in=entities_tr)
| Q(parent__in=entities_meta, child__in=entities_meta)
).select_related("role", "child__type", "parent__type").order_by("parent__name")
@extend_schema_view(
post=extend_schema(
operation_id="CreateTranscriptionEntities",
Loading