Skip to content

Commit bd7da79

Browse files
committed
Database independent design
1 parent b44bc08 commit bd7da79

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

flask_rest_jsonapi/data_layers/alchemy.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,21 @@ def get_object(self, view_kwargs, qs=None):
9999

100100
return obj
101101

102-
def get_collection(self, qs, view_kwargs):
102+
def get_collection(self, qs, view_kwargs, filters=None):
103103
"""Retrieve a collection of objects through sqlalchemy
104104
105105
:param QueryStringManager qs: a querystring manager to retrieve information from url
106106
:param dict view_kwargs: kwargs from the resource view
107+
:param dict filters: A dictionary of key/value filters to apply to the eventual query
107108
:return tuple: the number of object and the list of objects
108109
"""
109110
self.before_get_collection(qs, view_kwargs)
110111

111112
query = self.query(view_kwargs)
112113

114+
if filters:
115+
query = query.filter_by(**filters)
116+
113117
if qs.filters:
114118
query = self.filter_query(query, qs.filters, self.model)
115119

flask_rest_jsonapi/data_layers/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ def get_object(self, view_kwargs):
6060
"""
6161
raise NotImplementedError
6262

63-
def get_collection(self, qs, view_kwargs):
63+
def get_collection(self, qs, view_kwargs, filters=None):
6464
"""Retrieve a collection of objects
6565
6666
:param QueryStringManager qs: a querystring manager to retrieve information from url
6767
:param dict view_kwargs: kwargs from the resource view
68+
:param dict filters: A dictionary of key/value filters to apply to the eventual query
6869
:return tuple: the number of object and the list of objects
6970
"""
7071
raise NotImplementedError

flask_rest_jsonapi/resource.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from flask_rest_jsonapi.data_layers.base import BaseDataLayer
2222
from flask_rest_jsonapi.data_layers.alchemy import SqlalchemyDataLayer
2323
from flask_rest_jsonapi.utils import JSONEncoder
24+
from marshmallow_jsonapi.fields import BaseRelationship
2425

2526

2627
class ResourceMeta(MethodViewType):
@@ -116,7 +117,8 @@ def get(self, *args, **kwargs):
116117

117118
qs = QSManager(request.args, self.schema)
118119

119-
objects_count, objects = self.get_collection(qs, kwargs)
120+
parent_filter = self._get_parent_filter(request.url, kwargs)
121+
objects_count, objects = self.get_collection(qs, kwargs, filters=parent_filter)
120122

121123
schema_kwargs = getattr(self, 'get_schema_kwargs', dict())
122124
schema_kwargs.update({'many': True})
@@ -190,6 +192,23 @@ def post(self, *args, **kwargs):
190192

191193
return result
192194

195+
def _get_parent_filter(self, url, kwargs):
196+
"""
197+
Returns a dictionary of filters that should be applied to ensure only resources
198+
belonging to the parent resource are returned
199+
"""
200+
201+
url_segments = url.split('/')
202+
parent_segment = url_segments[-3]
203+
parent_id = url_segments[-2]
204+
205+
for key, value in self.schema._declared_fields.items():
206+
if isinstance(value, BaseRelationship):
207+
if value.type_ == parent_segment:
208+
return {value.id_field: parent_id}
209+
210+
return {}
211+
193212
def before_get(self, args, kwargs):
194213
"""Hook to make custom work before get method"""
195214
pass
@@ -209,8 +228,8 @@ def after_post(self, result):
209228
def before_marshmallow(self, args, kwargs):
210229
pass
211230

212-
def get_collection(self, qs, kwargs):
213-
return self._data_layer.get_collection(qs, kwargs)
231+
def get_collection(self, qs, kwargs, filters=None):
232+
return self._data_layer.get_collection(qs, kwargs, filters=filters)
214233

215234
def create_object(self, data, kwargs):
216235
return self._data_layer.create_object(data, kwargs)

0 commit comments

Comments
 (0)