diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py index f5d1bfd6e5c6cf19faee615d6932d8bd6a05c67c..209a015854feb19ac86798d42fad2d14cc48c44e 100644 --- a/arkindex/documents/api/elements.py +++ b/arkindex/documents/api/elements.py @@ -58,7 +58,7 @@ from arkindex.documents.serializers.elements import ( ElementTypeSerializer, MetaDataBulkSerializer, MetaDataCreateSerializer, - MetaDataUpdateSerializer, + MetaDataSerializer, SelectionMoveSerializer, SelectionParentCreateSerializer, ) @@ -1660,7 +1660,7 @@ class ElementMetadata(ListCreateAPIView): ) else: qs = element.metadatas.all() - return qs.select_related('entity') + return qs.select_related('entity__worker_run', 'worker_run') def get_queryset(self): if self.request and self.request.method == 'GET': @@ -1737,11 +1737,16 @@ class MetadataEdit(ACLMixin, RetrieveUpdateDestroyAPIView): Edit an existing element medadata """ permission_classes = (IsVerified, ) - serializer_class = MetaDataUpdateSerializer + serializer_class = MetaDataSerializer def get_queryset(self): # Filter readable metadata in order to check object permissions - return MetaData.objects.select_related('element__corpus').filter(element__corpus__in=Corpus.objects.readable(self.request.user)) + return ( + MetaData + .objects + .select_related('element__corpus', 'worker_run', 'entity__worker_run') + .filter(element__corpus__in=Corpus.objects.readable(self.request.user)) + ) def check_object_permissions(self, request, obj): super().check_object_permissions(request, obj) diff --git a/arkindex/documents/serializers/elements.py b/arkindex/documents/serializers/elements.py index fd05dc4e5bf0da81ae368aa4ad3edd9ba91522ce..2ba0da45eae82f2237ea5a79cbf43d9b8f56bbc0 100644 --- a/arkindex/documents/serializers/elements.py +++ b/arkindex/documents/serializers/elements.py @@ -34,17 +34,6 @@ from arkindex.users.models import Role from arkindex.users.utils import get_max_level -class MetaDataSerializer(MetaDataLightSerializer): - """ - Serialises some Metadata for any Element - """ - entity = BaseEntitySerializer(read_only=True) - - class Meta: - model = MetaData - fields = MetaDataLightSerializer.Meta.fields + ('entity', ) - - def metadata_number_validator(data, serializer): # Those can be None if someone messed up their input; DRF will catch it itself afterwards, so we ignore None. meta_type = data.get('type', serializer.instance.type if serializer.instance else None) @@ -85,10 +74,8 @@ metadata_number_validator.requires_context = True metadata_url_validator.requires_context = True -class MetaDataUpdateSerializer(MetaDataSerializer): - """ - Allow editing MetaData - """ +class MetaDataSerializer(MetaDataLightSerializer): + entity = BaseEntitySerializer(read_only=True, allow_null=True) entity_id = serializers.PrimaryKeyRelatedField( source='entity', queryset=Entity.objects.none(), @@ -97,15 +84,23 @@ class MetaDataUpdateSerializer(MetaDataSerializer): allow_null=True, style={'base_template': 'input.html'}, ) + worker_run = WorkerRunSummarySerializer(read_only=True, allow_null=True) - class Meta: - model = MetaData - fields = MetaDataSerializer.Meta.fields + ('entity_id', 'worker_version', 'worker_run_id', ) - read_only_fields = ('worker_version', 'worker_run_id', ) + class Meta(MetaDataLightSerializer.Meta): + fields = MetaDataLightSerializer.Meta.fields + ( + 'entity_id', + 'entity', + 'worker_version', + 'worker_run', + ) + read_only_fields = MetaDataLightSerializer.Meta.read_only_fields + ( + 'entity', + 'worker_version', + 'worker_run', + ) validators = [ metadata_number_validator, metadata_url_validator, - WorkerRunOrVersionValidator(worker_version_field='worker_version', ), ] def __init__(self, *args, **kwargs): @@ -127,7 +122,7 @@ class MetaDataUpdateSerializer(MetaDataSerializer): return data -class MetaDataCreateSerializer(MetaDataUpdateSerializer): +class MetaDataCreateSerializer(MetaDataSerializer): worker_version = serializers.PrimaryKeyRelatedField( queryset=WorkerVersion.objects.all(), required=False, @@ -137,13 +132,20 @@ class MetaDataCreateSerializer(MetaDataUpdateSerializer): worker_run_id = serializers.PrimaryKeyRelatedField( queryset=WorkerRun.objects.all(), required=False, + write_only=True, allow_null=True, style={'base_template': 'input.html'}, source='worker_run' ) - class Meta(MetaDataUpdateSerializer.Meta): + class Meta(MetaDataSerializer.Meta): + fields = MetaDataSerializer.Meta.fields + ( + 'worker_run_id', + ) read_only_fields = () + validators = MetaDataSerializer.Meta.validators + [ + WorkerRunOrVersionValidator(worker_version_field='worker_version'), + ] class MetaDataBulkItemSerializer(MetaDataLightSerializer): diff --git a/arkindex/documents/serializers/light.py b/arkindex/documents/serializers/light.py index 84bd8192e73e0f3e737c2060e52c06ee13a6c2ff..c885dfab4f1ea9585562f189e863f665fccd19e6 100644 --- a/arkindex/documents/serializers/light.py +++ b/arkindex/documents/serializers/light.py @@ -105,9 +105,6 @@ class CorpusLightSerializer(serializers.ModelSerializer): class MetaDataLightSerializer(serializers.ModelSerializer): - """ - Serialize a metadata without its entity - """ type = EnumField(MetaType) dates = InterpretedDateSerializer(many=True, source='get_dates', read_only=True) value = MetaDataValueField( diff --git a/arkindex/documents/tests/test_metadata.py b/arkindex/documents/tests/test_metadata.py index cbe8e1d7d0c2f7b360ba7469ef147f41d8eb566d..7ad31ef483b20013f05e5e383747e792e0d9c189 100644 --- a/arkindex/documents/tests/test_metadata.py +++ b/arkindex/documents/tests/test_metadata.py @@ -50,7 +50,7 @@ class TestMetaData(FixtureAPITestCase): 'dates': [], 'entity': None, 'worker_version': None, - 'worker_run_id': None + 'worker_run': None }, ]) @@ -68,7 +68,7 @@ class TestMetaData(FixtureAPITestCase): 'dates': [], 'entity': None, 'worker_version': None, - 'worker_run_id': None, + 'worker_run': None, }, ]) @@ -102,7 +102,7 @@ class TestMetaData(FixtureAPITestCase): 'value': '123', 'entity': None, 'worker_version': None, - 'worker_run_id': None + 'worker_run': None }, { 'id': str(entity_meta.id), @@ -121,7 +121,7 @@ class TestMetaData(FixtureAPITestCase): 'worker_run': None, }, 'worker_version': None, - 'worker_run_id': None, + 'worker_run': None, }, ]) @@ -141,10 +141,36 @@ class TestMetaData(FixtureAPITestCase): 'value': '123', 'entity': None, 'worker_version': str(self.worker_version.id), - 'worker_run_id': None + 'worker_run': None }, ]) + def test_list_with_worker_run(self): + self.metadata.worker_version = self.worker_version + self.metadata.worker_run = self.worker_run + self.metadata.save() + self.client.force_login(self.user) + + with self.assertNumQueries(6): + response = self.client.get(reverse('api:element-metadata', kwargs={'pk': str(self.vol.id)})) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.assertListEqual(response.json(), [ + { + 'id': str(self.metadata.id), + 'name': 'folio', + 'type': 'text', + 'value': '123', + 'entity': None, + 'dates': [], + 'worker_version': str(self.worker_version.id), + 'worker_run': { + 'id': str(self.worker_run.id), + 'summary': 'Worker Document layout analyser @ 418bd4', + } + } + ]) + def test_list_wrong_acl(self): self.vol.corpus = self.private_corpus self.vol.save() @@ -173,7 +199,7 @@ class TestMetaData(FixtureAPITestCase): 'name': 'folio', 'type': 'text', 'value': '1r', - 'worker_run_id': None, + 'worker_run': None, 'worker_version': None, }]) @@ -207,7 +233,7 @@ class TestMetaData(FixtureAPITestCase): 'dates': [], 'entity': None, 'worker_version': None, - 'worker_run_id': None, + 'worker_run': None, }, { 'dates': [], @@ -217,7 +243,7 @@ class TestMetaData(FixtureAPITestCase): 'value': '1r', 'entity': None, 'worker_version': None, - 'worker_run_id': None, + 'worker_run': None, }, { 'dates': [], @@ -226,7 +252,7 @@ class TestMetaData(FixtureAPITestCase): 'name': 'weigth', 'type': 'numeric', 'value': 1337.0, - 'worker_run_id': None, + 'worker_run': None, 'worker_version': None, }, ], @@ -297,6 +323,19 @@ class TestMetaData(FixtureAPITestCase): self.assertEqual(md.value, 'Texas') self.assertEqual(md.worker_run_id, self.worker_run.id) self.assertEqual(md.worker_version, self.worker_version) + self.assertDictEqual(response.json(), { + 'id': str(md.id), + 'name': 'location', + 'type': 'location', + 'value': 'Texas', + 'entity': None, + 'dates': [], + 'worker_version': str(self.worker_version.id), + 'worker_run': { + 'id': str(self.worker_run.id), + 'summary': 'Worker Document layout analyser @ 418bd4', + } + }) def test_create_metadata_worker_run_or_version(self): self.client.force_login(self.user) @@ -339,7 +378,7 @@ class TestMetaData(FixtureAPITestCase): 'year': 1885 }], 'worker_version': None, - 'worker_run_id': None + 'worker_run': None }) def test_create_metadata_empty(self): @@ -508,7 +547,7 @@ class TestMetaData(FixtureAPITestCase): 'value': '2019-12-04', 'entity': None, 'worker_version': None, - 'worker_run_id': None + 'worker_run': None }) self.metadata.refresh_from_db() self.assertEqual(self.metadata.type, MetaType.Date) @@ -641,7 +680,7 @@ class TestMetaData(FixtureAPITestCase): 'value': '2019-12-04', 'entity': None, 'worker_version': None, - 'worker_run_id': None + 'worker_run': None }) self.metadata.refresh_from_db() self.assertEqual(self.metadata.type, MetaType.Date) @@ -667,7 +706,7 @@ class TestMetaData(FixtureAPITestCase): 'value': '123', 'entity': None, 'worker_version': None, - 'worker_run_id': None + 'worker_run': None }) self.metadata.refresh_from_db() self.assertEqual(self.metadata.type, MetaType.Date) @@ -692,7 +731,7 @@ class TestMetaData(FixtureAPITestCase): 'value': '2019-12-04', 'entity': None, 'worker_version': None, - 'worker_run_id': None + 'worker_run': None }) self.metadata.refresh_from_db() self.assertEqual(self.metadata.type, MetaType.Text) @@ -831,8 +870,11 @@ class TestMetaData(FixtureAPITestCase): def test_get_metadata(self): self.client.force_login(self.user) - response = self.client.get(reverse('api:metadata-edit', kwargs={'pk': str(self.metadata.id)})) - self.assertEqual(response.status_code, status.HTTP_200_OK) + + with self.assertNumQueries(6): + response = self.client.get(reverse('api:metadata-edit', kwargs={'pk': str(self.metadata.id)})) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertDictEqual( response.json(), { @@ -843,7 +885,7 @@ class TestMetaData(FixtureAPITestCase): 'entity': None, 'dates': [], 'worker_version': None, - 'worker_run_id': None + 'worker_run': None } ) @@ -854,8 +896,11 @@ class TestMetaData(FixtureAPITestCase): self.metadata.type = MetaType.Numeric self.metadata.save() self.client.force_login(self.user) - response = self.client.get(reverse('api:metadata-edit', kwargs={'pk': str(self.metadata.id)})) - self.assertEqual(response.status_code, status.HTTP_200_OK) + + with self.assertNumQueries(6): + response = self.client.get(reverse('api:metadata-edit', kwargs={'pk': str(self.metadata.id)})) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertDictEqual( response.json(), { @@ -866,10 +911,34 @@ class TestMetaData(FixtureAPITestCase): 'entity': None, 'dates': [], 'worker_version': None, - 'worker_run_id': None + 'worker_run': None } ) + def test_get_metadata_worker_run(self): + self.metadata.worker_version = self.worker_version + self.metadata.worker_run = self.worker_run + self.metadata.save() + self.client.force_login(self.user) + + with self.assertNumQueries(6): + response = self.client.get(reverse('api:metadata-edit', kwargs={'pk': str(self.metadata.id)})) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.assertDictEqual(response.json(), { + 'id': str(self.metadata.id), + 'name': 'folio', + 'type': 'text', + 'value': '123', + 'entity': None, + 'dates': [], + 'worker_version': str(self.worker_version.id), + 'worker_run': { + 'id': str(self.worker_run.id), + 'summary': 'Worker Document layout analyser @ 418bd4', + } + }) + def test_create_metadata_entity(self): self.client.force_login(self.superuser) entity = self.corpus.entities.create( @@ -961,7 +1030,7 @@ class TestMetaData(FixtureAPITestCase): 'entity': None, 'dates': [], 'worker_version': None, - 'worker_run_id': None + 'worker_run': None } ) @@ -980,7 +1049,7 @@ class TestMetaData(FixtureAPITestCase): 'entity': None, 'dates': [], 'worker_version': None, - 'worker_run_id': None + 'worker_run': None } ) @@ -999,7 +1068,7 @@ class TestMetaData(FixtureAPITestCase): 'entity': None, 'dates': [], 'worker_version': None, - 'worker_run_id': None + 'worker_run': None } )