Skip to content

Commit c02f419

Browse files
authored
Merge pull request #48 from salesforce/bugfix/apply-filters-to-dicts
Bugfix/apply filters to dicts
2 parents 390f524 + 635716a commit c02f419

File tree

10 files changed

+68
-18
lines changed

10 files changed

+68
-18
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.22.1
2+
current_version = 0.22.2
33

44
[bumpversion:file:setup.py]
55

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic
66
Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
# [0.22.2] - 2020-08-11
9+
### Fixed
10+
- [PR](https://github.com/salesforce/django-declarative-apis/pull/48) Apply filters to dict values
11+
812
# [0.22.1] - 2020-08-11
913
### Fixed
1014
- [PR]() Fix travis config

django_declarative_apis/machinery/__init__.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -182,19 +182,6 @@ def get_response(self):
182182
return status_code, data
183183
else:
184184
raise HttpStatusCode(data)
185-
elif isinstance(data, dict):
186-
result = {}
187-
for key, value in data.items():
188-
if isinstance(value, (list, tuple, models.query.QuerySet)):
189-
result[key] = []
190-
for item in value:
191-
result[key].append(
192-
apply_filters_to_object(item, filter_def)
193-
)
194-
else:
195-
result[key] = value
196-
197-
return status_code, result
198185
else:
199186
return (
200187
status_code,

django_declarative_apis/machinery/filtering.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ def _apply_filters_to_object(inst, filter_def, expand_children=None, klass=None)
115115
)
116116
for item in inst
117117
]
118+
elif isinstance(inst, (dict,)):
119+
return {
120+
k: _apply_filters_to_object(
121+
v, filter_def, expand_children=expand_children, klass=v.__class__
122+
)
123+
for k, v in inst.items()
124+
}
118125

119126
fields_def = filter_def.get(klass)
120127
if fields_def is None:

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
# built documents.
7474

7575
# The full version, including alpha/beta/rc tags.
76-
release = '0.22.1' # set by bumpversion
76+
release = '0.22.2' # set by bumpversion
7777

7878
# The short X.Y version.
7979
version = release.rsplit('.', 1)[0]

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
setuptools.setup(
2222
name="django-declarative-apis",
23-
version="0.22.1", # set by bumpversion
23+
version="0.22.2", # set by bumpversion
2424
author="Drew Shafer",
2525
url="https://salesforce.com",
2626
description="Simple, readable, declarative APIs for Django",

tests/machinery/test_base.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import kombu.exceptions
1515
import mock
1616
from django.core.cache import cache
17+
from django.http import HttpRequest
1718

1819
import tests.models
1920
from django_declarative_apis import machinery, models as dda_models
@@ -291,10 +292,15 @@ def resource(self):
291292
def response(self):
292293
return {"people": self.resource}
293294

295+
def __call__(self):
296+
return self
297+
294298
endpoint = _TestEndpoint()
295299
manager = machinery.EndpointBinder.BoundEndpointManager(
296300
machinery._EndpointRequestLifecycleManager(endpoint), endpoint
297301
)
302+
machinery.EndpointBinder(endpoint).create_bound_endpoint(manager, HttpRequest())
303+
298304
status, resp = manager.get_response()
299305
self.assertEqual(status, http.HTTPStatus.OK)
300306
# make sure the list is in the expected order
@@ -723,7 +729,12 @@ def __init__(self, expected_response, *args, **kwargs):
723729
super(_TestEndpoint, self).__init__(*args, **kwargs)
724730
self.expected_response = expected_response
725731

726-
@machinery.endpoint_resource(type=tests.models.TestModel, filter={"foo": "bar"})
732+
def __call__(self):
733+
return self
734+
735+
@machinery.endpoint_resource(
736+
type=tests.models.TestModel, filter={str: filtering.ALWAYS}
737+
)
727738
def resource(self):
728739
return tests.models.TestModel(int_field=0)
729740

@@ -785,6 +796,7 @@ def test_get_response_kombu_error_retried(self):
785796
manager = machinery.EndpointBinder.BoundEndpointManager(
786797
machinery._EndpointRequestLifecycleManager(endpoint), endpoint
787798
)
799+
machinery.EndpointBinder(endpoint).create_bound_endpoint(manager, HttpRequest())
788800

789801
conf = tasks.future_task_runner.app.conf
790802
old_val = conf["task_always_eager"]
@@ -824,6 +836,7 @@ def test_async_task_falls_back_to_synchronous_when_configured(self):
824836
manager = machinery.EndpointBinder.BoundEndpointManager(
825837
machinery._EndpointRequestLifecycleManager(endpoint), endpoint
826838
)
839+
machinery.EndpointBinder(endpoint).create_bound_endpoint(manager, HttpRequest())
827840

828841
conf = tasks.future_task_runner.app.conf
829842
old_val = conf["task_always_eager"]
@@ -852,6 +865,7 @@ def test_force_synchronous_tasks(self):
852865
manager = machinery.EndpointBinder.BoundEndpointManager(
853866
machinery._EndpointRequestLifecycleManager(endpoint), endpoint
854867
)
868+
machinery.EndpointBinder(endpoint).create_bound_endpoint(manager, HttpRequest())
855869

856870
conf = tasks.future_task_runner.app.conf
857871
old_val = conf["task_always_eager"]
@@ -881,6 +895,7 @@ def test_get_response_kombu_error_attempts_exceeded(self):
881895
manager = machinery.EndpointBinder.BoundEndpointManager(
882896
machinery._EndpointRequestLifecycleManager(endpoint), endpoint
883897
)
898+
machinery.EndpointBinder(endpoint).create_bound_endpoint(manager, HttpRequest())
884899

885900
conf = tasks.future_task_runner.app.conf
886901
old_val = conf["task_always_eager"]
@@ -924,6 +939,7 @@ def test_get_response_success(self):
924939
manager = machinery.EndpointBinder.BoundEndpointManager(
925940
machinery._EndpointRequestLifecycleManager(endpoint), endpoint
926941
)
942+
machinery.EndpointBinder(endpoint).create_bound_endpoint(manager, HttpRequest())
927943

928944
# can't use mock.patch.dict here because it doesn't implement the api that the unpatcher expects
929945
conf = tasks.future_task_runner.app.conf

tests/tests.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,29 @@ def test_simplest_endpoint(self):
2828
"/simple", consumer=self.consumer, expected_status_code=HTTPStatus.OK
2929
)
3030

31+
def test_dict_endpoint(self):
32+
resp = self.client.get(
33+
"/dict", consumer=self.consumer, expected_status_code=HTTPStatus.OK
34+
)
35+
data = resp.json()
36+
self.assertEqual(
37+
data,
38+
{
39+
"test": {
40+
"pk": 1,
41+
"int_field": 1,
42+
"__expandable__": ["expandable_dict", "expandable_string"],
43+
},
44+
"deep_test": {
45+
"test": {
46+
"pk": 1,
47+
"int_field": 1,
48+
"__expandable__": ["expandable_dict", "expandable_string"],
49+
}
50+
},
51+
},
52+
)
53+
3154
def test_typed_parameter(self):
3255
response = self.client.get(
3356
"/simple?int_type_field=not_an_int",

tests/urls.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@
1313

1414
UUID4_REGEX = r"[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}"
1515

16-
urlpatterns = [url(r"^simple", resource_adapter(get=views.SimpleEndpointDefinition))]
16+
urlpatterns = [
17+
url(r"^simple", resource_adapter(get=views.SimpleEndpointDefinition)),
18+
url(r"^dict", resource_adapter(get=views.DictEndpointDefinition)),
19+
]

tests/views.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,13 @@ def execution_decider(self):
3434
@staticmethod
3535
def deferred_task(inst):
3636
cache.set("deferred_task_called", True)
37+
38+
39+
class DictEndpointDefinition(EndpointDefinition):
40+
def is_authorized(self):
41+
return True
42+
43+
@endpoint_resource(type=TestModel)
44+
def resource(self):
45+
inst = TestModel.objects.create(int_field=1)
46+
return {"test": inst, "deep_test": {"test": inst}}

0 commit comments

Comments
 (0)