Skip to content

Commit

Permalink
Ingest string values and perform listitem lookup #40 (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnatawnclementawn authored Oct 10, 2024
1 parent d7a338b commit d1b37d4
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 2 deletions.
14 changes: 14 additions & 0 deletions arches_references/datatypes/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from arches.app.datatypes.base import BaseDataType
from arches.app.models.graph import GraphValidationError

from arches_references.models import ListItem


class ReferenceDataType(BaseDataType):
def validate(
Expand Down Expand Up @@ -76,8 +78,20 @@ def validate(
return errors

def transform_value_for_tile(self, value, **kwargs):
list_id = kwargs.get("controlledList")
if isinstance(value, str):
found_item = self.lookup_listitem_from_label(value, list_id)
if found_item:
value = [found_item.build_tile_value()]
return value

def lookup_listitem_from_label(self, value, list_id):
return (
ListItem.objects.filter(list_id=list_id, list_item_values__value=value)
.order_by("sortorder")
.first()
)

def clean(self, tile, nodeid):
super().clean(tile, nodeid)
if tile.data[nodeid] == []:
Expand Down
12 changes: 10 additions & 2 deletions arches_references/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ def serialize(self, depth_map=None, flat=False):
)
return data

def build_tile_value(self):
tile_value = {
"uri": self.uri or self.generate_uri(),
"labels": [label.serialize() for label in self.list_item_values.labels()],
"listid": str(self.id),
}
return tile_value


class ListItemValue(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Expand Down Expand Up @@ -274,7 +282,7 @@ def serialize(self):
"valuetype_id": self.valuetype_id,
"language_id": self.language_id,
"value": self.value,
"list_item_id": self.list_item_id,
"list_item_id": str(self.list_item_id),
}

def delete(self):
Expand Down Expand Up @@ -313,7 +321,7 @@ class Meta:
def serialize(self):
return {
"id": str(self.id),
"list_item_id": self.list_item_id,
"list_item_id": str(self.list_item_id),
"url": self.value.url,
"metadata": [
metadata.serialize() for metadata in self.list_item_image_metadata.all()
Expand Down
3 changes: 3 additions & 0 deletions arches_references/querysets.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class ListItemValueQuerySet(models.QuerySet):
def values_without_images(self):
return self.exclude(valuetype="image")

def labels(self):
return self.filter(valuetype__category="label")

def images(self):
return self.filter(valuetype="image")

Expand Down
37 changes: 37 additions & 0 deletions tests/reference_datatype_tests.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
from arches.app.datatypes.datatypes import DataTypeFactory
from arches.app.models.tile import Tile
from arches_references.models import List, ListItem, ListItemValue
from django.test import TestCase

# these tests can be run from the command line via
# python manage.py test tests.reference_datatype_tests --settings="tests.test_settings"


class ReferenceDataTypeTests(TestCase):

@classmethod
def setUpTestData(cls):
from tests.test_views import ListTests

return ListTests.setUpTestData()

def test_validate(self):
reference = DataTypeFactory().get_instance("reference")

Expand Down Expand Up @@ -86,3 +94,32 @@ def test_tile_clean(self):
tile1.data[nodeid] = []
reference.clean(tile1, nodeid)
self.assertIsNone(tile1.data[nodeid])

def test_transform_value_for_tile(self):
reference = DataTypeFactory().get_instance("reference")
list1_pk = str(List.objects.get(name="list1").pk)
config = {"controlledList": list1_pk}

tile_value1 = reference.transform_value_for_tile("label1-pref", **config)
self.assertTrue(isinstance(tile_value1, list))
self.assertTrue("uri" in tile_value1[0])
self.assertTrue("labels" in tile_value1[0])
self.assertTrue("listid" in tile_value1[0])

self.assertIsNone(reference.transform_value_for_tile(None, **config))

# Test deterministic sorting:
# Force two items to have the same prefLabel in a list,
# expect the list item with lower sortorder to be returned
expected_list_item_pk = str(
ListItem.objects.get(
list_item_values__value="label2-pref", list_id=list1_pk
).pk
)
ListItemValue.objects.filter(
value="label3-pref", list_item_id__list_id=list1_pk
).update(value="label2-pref")
tile_value2 = reference.transform_value_for_tile("label2-pref", **config)
self.assertEqual(
tile_value2[0]["labels"][0]["list_item_id"], expected_list_item_pk
)

0 comments on commit d1b37d4

Please sign in to comment.