Skip to content

Commit

Permalink
✨[#414] add in operator to API
Browse files Browse the repository at this point in the history
  • Loading branch information
Coperh committed Aug 27, 2024
1 parent 79591dc commit d526b8a
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/objects/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ class Operators(models.TextChoices):
lt = "lt", _("lower than")
lte = "lte", _("lower than or equal to")
icontains = "icontains", _("case-insensitive partial match")
in_list = "in", _("contains")
6 changes: 6 additions & 0 deletions src/objects/api/v1/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ def filter_data_attrs(self, queryset, name, value: str):
queryset = queryset.filter(
**{f"data__{variable}__icontains": str_value}
)
elif operator == "in":
# in must be a list
values = str_value.split("|")
queryset = queryset.filter(
**{f"data__{variable}__in": values}
)

else:
# gt, gte, lt, lte operators
Expand Down
6 changes: 6 additions & 0 deletions src/objects/api/v2/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ def filter_data_attrs(self, queryset, name, value: str):
queryset = queryset.filter(
**{f"data__{variable}__icontains": str_value}
)
elif operator == "in":
# in must be a list
values = str_value.split("|")
queryset = queryset.filter(
**{f"data__{variable}__in": values}
)

else:
# gt, gte, lt, lte operators
Expand Down
2 changes: 1 addition & 1 deletion src/objects/api/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def validate_data_attrs(value: str):
}
raise serializers.ValidationError(message, code=code)

if operator not in (Operators.exact, Operators.icontains) and isinstance(
if operator not in (Operators.exact, Operators.icontains, Operators.in_list) and isinstance(
string_to_value(val), str
):
message = _(
Expand Down
25 changes: 25 additions & 0 deletions src/objects/tests/v1/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,31 @@ def test_filter_exclude_old_records(self):
data = response.json()
self.assertEqual(len(data), 0)

def test_filter_in_string(self):
record = ObjectRecordFactory.create(
data={"name": "demo1"}, object__object_type=self.object_type
)
record2 = ObjectRecordFactory.create(
data={"name": "demo2"}, object__object_type=self.object_type
)
ObjectRecordFactory.create(
data={"name": "demo3"}, object__object_type=self.object_type
)

response = self.client.get(self.url, {"data_attrs": "name__in__demo1|demo2"})
self.assertEqual(response.status_code, status.HTTP_200_OK)

data = response.json()
self.assertEqual(len(data), 2)
self.assertEqual(
data[0]["url"],
f"http://testserver{reverse('object-detail', args=[record2.object.uuid])}",
)
self.assertEqual(
data[1]["url"],
f"http://testserver{reverse('object-detail', args=[record.object.uuid])}",
)


class FilterDateTests(TokenAuthMixin, APITestCase):
@classmethod
Expand Down
27 changes: 27 additions & 0 deletions src/objects/tests/v2/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,33 @@ def test_filter_date_field_gte(self):

self.assertEqual(len(data), 0)

def test_filter_in_string(self):
record = ObjectRecordFactory.create(
data={"name": "demo1"}, object__object_type=self.object_type
)
record2 = ObjectRecordFactory.create(
data={"name": "demo2"}, object__object_type=self.object_type
)
ObjectRecordFactory.create(
data={"name": "demo3"}, object__object_type=self.object_type
)

response = self.client.get(self.url, {"data_attrs": "name__in__demo1|demo2"})

self.assertEqual(response.status_code, status.HTTP_200_OK)

data = response.json()["results"]

self.assertEqual(len(data), 2)
self.assertEqual(
data[0]["url"],
f"http://testserver{reverse('object-detail', args=[record2.object.uuid])}",
)
self.assertEqual(
data[1]["url"],
f"http://testserver{reverse('object-detail', args=[record.object.uuid])}",
)


class FilterDateTests(TokenAuthMixin, APITestCase):
@classmethod
Expand Down

0 comments on commit d526b8a

Please sign in to comment.