diff --git a/arkindex/documents/api/entities.py b/arkindex/documents/api/entities.py index a65be3ab6161df80413d7746b165059470905e15..372f95e62b614e56a4d031620e9a31675aac4d4c 100644 --- a/arkindex/documents/api/entities.py +++ b/arkindex/documents/api/entities.py @@ -5,10 +5,9 @@ from rest_framework.generics import \ ListAPIView, ListCreateAPIView, RetrieveAPIView, CreateAPIView, RetrieveUpdateDestroyAPIView from arkindex.documents.serializers.entities import ( EntityRoleSerializer, EntitySerializer, EntityCreateSerializer, EntityLinkCreateSerializer, - TranscriptionEntitySerializer, TranscriptionEntityDetailsSerializer, ElementEntitiesSerializer, - EntityLinkSerializer, + TranscriptionEntitySerializer, TranscriptionEntityDetailsSerializer, EntityLinkSerializer, ) -from arkindex.documents.serializers.elements import ElementSlimSerializer +from arkindex.documents.serializers.elements import ElementSlimSerializer, ElementEntitiesSerializer from rest_framework import serializers, status from rest_framework.exceptions import NotFound from rest_framework.response import Response diff --git a/arkindex/documents/serializers/elements.py b/arkindex/documents/serializers/elements.py index e0d50bce6e33806e3aa86cc5e9f2f5519e56de9e..21fd938ab09cfc6b04bd6f69a9a7d8fc3ea2cd43 100644 --- a/arkindex/documents/serializers/elements.py +++ b/arkindex/documents/serializers/elements.py @@ -3,13 +3,16 @@ from rest_framework.exceptions import ValidationError from arkindex_common.ml_tool import MLToolType from arkindex_common.enums import MetaType from arkindex.dataimport.models import WorkerVersion -from arkindex.documents.models import Corpus, Element, ElementPath, ElementType, MetaData, Entity +from arkindex.documents.models import ( + Corpus, Element, ElementPath, ElementType, MetaData, + Entity, Transcription, TranscriptionEntity, +) from arkindex.images.serializers import ZoneSerializer from arkindex.images.models import Image, Zone from arkindex.documents.serializers.light import ( - CorpusLightSerializer, ElementLightSerializer, ElementTypeSerializer, - EntityLightSerializer, MetaDataLightSerializer, + CorpusLightSerializer, ElementLightSerializer, ElementTypeSerializer, MetaDataLightSerializer ) +from arkindex.documents.serializers.entities import BaseEntitySerializer, TranscriptionEntityDetailsSerializer from arkindex.documents.serializers.ml import ClassificationSerializer, DataSourceSerializer from arkindex.project.serializer_fields import PolygonField, DataSourceSlugField from arkindex.project.polygon import Polygon @@ -20,7 +23,7 @@ class MetaDataSerializer(MetaDataLightSerializer): """ Serialises some Metadata for any Element """ - entity = EntityLightSerializer() + entity = BaseEntitySerializer() class Meta: model = MetaData @@ -408,3 +411,39 @@ class ElementCreateSerializer(ElementLightSerializer): return {"id": instance.id} return ElementSerializer(instance, context=self.context).data + + +class ElementEntitiesSerializer(ElementLightSerializer): + """ + Serialize an element with its entities + Entities are split into two types, those extracted + from metadata and those extracted from element transcriptions + """ + metadata = MetaDataSerializer(many=True) + transcriptions = TranscriptionEntityDetailsSerializer(many=True) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if not self.context.get('request'): + # Keep original fields so OpenAPI can build its schemas + return + self.fields['transcriptions'] = serializers.SerializerMethodField() + self.fields['metadata'] = serializers.SerializerMethodField() + + def get_transcriptions(self, obj): + elt_transcriptions = Transcription.objects.filter(element_id=obj.id) + transcription_entities = TranscriptionEntity.objects \ + .filter(transcription__in=elt_transcriptions) \ + .prefetch_related('entity') \ + .order_by('offset') + return TranscriptionEntityDetailsSerializer(transcription_entities, many=True).data + + def get_metadata(self, obj): + metadata = obj.metadatas \ + .filter(entity__isnull=False) \ + .prefetch_related('revision__repo', 'entity') + return MetaDataSerializer(metadata, many=True).data + + class Meta: + model = Element + fields = ElementLightSerializer.Meta.fields + ('transcriptions', 'metadata') diff --git a/arkindex/documents/serializers/entities.py b/arkindex/documents/serializers/entities.py index d65a2037b52c16787d55ee0ee1929985a76a76da..bfb5f9192a8e61931cd8fc0a3519024eb685f72f 100644 --- a/arkindex/documents/serializers/entities.py +++ b/arkindex/documents/serializers/entities.py @@ -4,14 +4,40 @@ from arkindex_common.ml_tool import MLToolType from arkindex.project.serializer_fields import EnumField, DataSourceSlugField from arkindex.dataimport.models import WorkerVersion from arkindex.documents.models import \ - Element, Corpus, Entity, EntityLink, EntityRole, Transcription, TranscriptionEntity + Corpus, Entity, EntityLink, EntityRole, TranscriptionEntity from arkindex_common.enums import EntityType -from arkindex.documents.serializers.light import \ - ElementLightSerializer, EntityLightSerializer, CorpusLightSerializer -from arkindex.documents.serializers.elements import MetaDataSerializer +from arkindex.documents.serializers.light import CorpusLightSerializer, InterpretedDateSerializer +from arkindex.documents.serializers.ml import DataSourceSerializer from arkindex.project.triggers import reindex_start +class BaseEntitySerializer(serializers.ModelSerializer): + """ + Serializes an entity + """ + type = EnumField(EntityType) + dates = InterpretedDateSerializer(many=True, source='get_dates', read_only=True) + metas = serializers.HStoreField(child=serializers.CharField(), required=False, allow_null=True) + source = DataSourceSerializer(read_only=True) + + class Meta: + model = Entity + fields = ( + 'id', + 'name', + 'type', + 'metas', + 'validated', + 'dates', + 'source' + ) + read_only_fields = ( + 'id', + 'dates', + 'source', + ) + + class EntityRoleSerializer(serializers.ModelSerializer): """ Serialize a role between two types of entity @@ -47,8 +73,8 @@ class EntityLinkSerializer(serializers.ModelSerializer): """ Serialize an entity link with its child, parent and role """ - parent = EntityLightSerializer() - child = EntityLightSerializer() + parent = BaseEntitySerializer() + child = BaseEntitySerializer() role = EntityRoleSerializer() class Meta: @@ -61,7 +87,7 @@ class EntityLinkSerializer(serializers.ModelSerializer): ) -class EntitySerializer(EntityLightSerializer): +class EntitySerializer(BaseEntitySerializer): """ Serialize an entity with its metadata """ @@ -71,12 +97,12 @@ class EntitySerializer(EntityLightSerializer): class Meta: model = Entity - fields = EntityLightSerializer.Meta.fields + ( + fields = BaseEntitySerializer.Meta.fields + ( 'corpus', 'children', 'parents' ) - read_only_fields = EntityLightSerializer.Meta.read_only_fields = ( + read_only_fields = BaseEntitySerializer.Meta.read_only_fields = ( 'corpus', 'children', 'parents', @@ -93,7 +119,7 @@ class EntitySerializer(EntityLightSerializer): return updated_entity -class EntityCreateSerializer(EntityLightSerializer): +class EntityCreateSerializer(BaseEntitySerializer): """ Serialize an entity with a possible parents and children """ @@ -220,40 +246,4 @@ class TranscriptionEntityDetailsSerializer(TranscriptionEntitySerializer): """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['entity'] = EntityLightSerializer() - - -class ElementEntitiesSerializer(ElementLightSerializer): - """ - Serialize an element with its entities - Entities are split into two types, those extracted - from metadata and those extracted from element transcriptions - """ - metadata = MetaDataSerializer(many=True) - transcriptions = TranscriptionEntityDetailsSerializer(many=True) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - if not self.context.get('request'): - # Keep original fields so OpenAPI can build its schemas - return - self.fields['transcriptions'] = serializers.SerializerMethodField() - self.fields['metadata'] = serializers.SerializerMethodField() - - def get_transcriptions(self, obj): - elt_transcriptions = Transcription.objects.filter(element_id=obj.id) - transcription_entities = TranscriptionEntity.objects \ - .filter(transcription__in=elt_transcriptions) \ - .prefetch_related('entity') \ - .order_by('offset') - return TranscriptionEntityDetailsSerializer(transcription_entities, many=True).data - - def get_metadata(self, obj): - metadata = obj.metadatas \ - .filter(entity__isnull=False) \ - .prefetch_related('revision__repo', 'entity') - return MetaDataSerializer(metadata, many=True).data - - class Meta: - model = Element - fields = ElementLightSerializer.Meta.fields + ('transcriptions', 'metadata') + self.fields['entity'] = BaseEntitySerializer() diff --git a/arkindex/documents/serializers/light.py b/arkindex/documents/serializers/light.py index 29f84733757a3a0ceb1f342a5f9217a6ff06b9b4..06942deae33d2e4ae84643797bdfa704f1c7506e 100644 --- a/arkindex/documents/serializers/light.py +++ b/arkindex/documents/serializers/light.py @@ -1,10 +1,9 @@ from rest_framework import serializers from rest_framework.exceptions import ValidationError, APIException from django.db.models import Max -from arkindex.documents.models import Element, ElementType, Corpus, Entity, MetaData, AllowedMetaData -from arkindex_common.enums import EntityType, MetaType, TranscriptionType +from arkindex.documents.models import Element, ElementType, Corpus, MetaData, AllowedMetaData +from arkindex_common.enums import MetaType, TranscriptionType from arkindex.documents.dates import DateType -from arkindex.documents.serializers.ml import DataSourceSerializer from arkindex.dataimport.serializers.git import RevisionSerializer from arkindex.project.serializer_fields import EnumField from arkindex.project.triggers import reindex_start @@ -70,33 +69,6 @@ class CorpusLightSerializer(serializers.ModelSerializer): ) -class EntityLightSerializer(serializers.ModelSerializer): - """ - Serializes an entity - """ - type = EnumField(EntityType) - dates = InterpretedDateSerializer(many=True, source='get_dates', read_only=True) - metas = serializers.HStoreField(child=serializers.CharField(), required=False, allow_null=True) - source = DataSourceSerializer(read_only=True) - - class Meta: - model = Entity - fields = ( - 'id', - 'name', - 'type', - 'metas', - 'validated', - 'dates', - 'source' - ) - read_only_fields = ( - 'id', - 'dates', - 'source', - ) - - class DuplicatedMetadata(APIException): status_code = 200 default_detail = 'Metadata exists.'