Skip to content

Commit e3e1fed

Browse files
committed
Allow relationships to be compared to scalars
1 parent b44bc08 commit e3e1fed

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

flask_rest_jsonapi/data_layers/filtering/alchemy.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""Helper to create sqlalchemy filters according to filter querystring parameter"""
44

55
from sqlalchemy import and_, or_, not_
6+
from sqlalchemy.orm import RelationshipProperty
67

78
from flask_rest_jsonapi.exceptions import InvalidFilters
89
from flask_rest_jsonapi.schema import get_relationships, get_model_field
@@ -51,6 +52,9 @@ def resolve(self):
5152

5253
if isinstance(value, dict):
5354
return getattr(self.column, self.operator)(**value)
55+
elif isinstance(self.column.prop, RelationshipProperty) and isinstance(value, (int, str)):
56+
relationship_key = next(iter(self.column.prop.local_columns))
57+
return getattr(relationship_key, self.operator)(value)
5458
else:
5559
return getattr(self.column, self.operator)(value)
5660

flask_rest_jsonapi/resource.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def get(self, *args, **kwargs):
134134
add_pagination_links(result,
135135
objects_count,
136136
qs,
137-
url_for(self.view, _external=True, **view_kwargs))
137+
url_for(request.endpoint, _external=True, **view_kwargs))
138138

139139
result.update({'meta': {'count': objects_count}})
140140

tests/test_sqlalchemy_data_layer.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ def get(self):
373373

374374

375375
@pytest.fixture(scope="module")
376-
def query():
376+
def query(computer_model, person_model):
377377
def query_(self, view_kwargs):
378378
if view_kwargs.get('person_id') is not None:
379379
return self.session.query(computer_model).join(person_model).filter_by(person_id=view_kwargs['person_id'])
@@ -641,6 +641,26 @@ def test_get_list_with_simple_filter(client, register_routes, person, person_2):
641641
response = client.get('/persons' + '?' + querystring, content_type='application/vnd.api+json')
642642
assert response.status_code == 200
643643

644+
def test_get_list_relationship_filter(client, register_routes, person_computers,
645+
computer_schema, person, person_2, computer, session):
646+
"""
647+
Tests the ability to filter over a relationship using IDs, for example
648+
`GET /comments?filter[post]=1`
649+
Refer to the spec: https://jsonapi.org/recommendations/#filtering
650+
"""
651+
# We have two people in the database, one of which owns a computer
652+
person.computers.append(computer)
653+
session.commit()
654+
655+
querystring = urlencode({
656+
'filter[owner]': person.person_id
657+
})
658+
response = client.get('/computers?' + querystring, content_type='application/vnd.api+json')
659+
660+
# Check that the request worked, and returned the one computer we wanted
661+
assert response.status_code == 200
662+
assert len(response.json['data']) == 1
663+
644664
def test_get_list_disable_pagination(client, register_routes):
645665
with client:
646666
querystring = urlencode({'page[size]': 0})
@@ -1804,3 +1824,4 @@ def test_api_resources(app, person_list):
18041824
def test_relationship_containing_hyphens(client, register_routes, person_computers, computer_schema, person):
18051825
response = client.get('/persons/{}/relationships/computers-owned'.format(person.person_id), content_type='application/vnd.api+json')
18061826
assert response.status_code == 200
1827+

0 commit comments

Comments
 (0)