Skip to content

Commit 2a7737e

Browse files
author
Daan van der Kallen
committed
Make id filter work for combined endpoint
1 parent 3388534 commit 2a7737e

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

binder/plugins/views/combined.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def combined_view(request, router, names):
7575

7676
# Get filtered & annotated querysets per name
7777
querysets = {}
78-
for name in names:
78+
for i, name in enumerate(names):
7979
view = views[name]
8080

8181
queryset = view.get_queryset(request)
@@ -92,11 +92,39 @@ def combined_view(request, router, names):
9292
queryset = annotate(queryset, request, sub_include_annotations.get(''))
9393

9494
# filters
95-
filters = {
96-
'id' if k == f'.{name}' else k[len(name) + 2:]: v
97-
for k, v in request.GET.lists()
98-
if k == f'.{name}' or k.startswith(f'.{name}.')
99-
}
95+
filters = {}
96+
for k, v in request.GET.lists():
97+
if k == '.id' or k.startswith('.id:'):
98+
values = []
99+
for value in v:
100+
ids = []
101+
for id in value.split(','):
102+
try:
103+
id = int(id)
104+
except ValueError:
105+
# leave invalid values for the detailed view
106+
pass
107+
else:
108+
if id % len(names) == i:
109+
# this is a combined id that matches this view,
110+
# so we can convert it to an id for the model
111+
# itself
112+
id = str(id // len(names))
113+
else:
114+
# this id does not match this view, so we
115+
# convert it to an id that never matches any
116+
# model
117+
id = '-1'
118+
ids.append(id)
119+
values.append(','.join(ids))
120+
filters[k[1:]] = values
121+
122+
elif k == f'.{name}' or k.startswith(f'.{name}:'):
123+
filters['id' + k[len(name) + 1:]] = v
124+
125+
elif k.startswith(f'.{name}.'):
126+
filters[k[len(name) + 2:]] = v
127+
100128
for field, values in filters.items():
101129
for v in values:
102130
q, distinct = view._parse_filter(field, v, request, sub_include_annotations)

tests/test_combined.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,18 @@ def test_combined_order_by_multi_field(self):
152152
animal2.id * 2 + 1, # Harambe
153153
zoo1.id * 2, # Apenheul
154154
])
155+
156+
def test_combined_id_filter(self):
157+
zoo1 = Zoo.objects.create(name='Apenheul', founding_date='1980-01-01')
158+
zoo2 = Zoo.objects.create(name='Emmen', founding_date='1990-01-01')
159+
animal1 = Animal.objects.create(zoo=zoo1, name='Bokito', birth_date='1995-01-01')
160+
animal2 = Animal.objects.create(zoo=zoo2, name='Harambe', birth_date='1985-01-01')
161+
162+
res = self.client.get(f'/combined/zoo/animal/?.id:in={zoo1.id * 2},{animal2.id * 2 + 1}')
163+
self.assertEqual(res.status_code, 200)
164+
data = json.loads(res.content)
165+
ids = [obj['id'] for obj in data['data']]
166+
self.assertEqual(ids, [
167+
zoo1.id * 2, # Apenheul
168+
animal2.id * 2 + 1, # Harambe
169+
])

0 commit comments

Comments
 (0)