Skip to content

Commit f97660a

Browse files
authored
Merge pull request #40 from iamareebjamal/patch-1
feat: Allow fetching multiple relationships from same included resource
2 parents f426ebb + 634f24d commit f97660a

File tree

2 files changed

+78
-3
lines changed

2 files changed

+78
-3
lines changed

flask_combo_jsonapi/schema.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def compute_schema(schema_cls, default_kwargs, qs, include):
2121
"""
2222
# manage include_data parameter of the schema
2323
schema_kwargs = default_kwargs
24-
schema_kwargs['include_data'] = tuple()
24+
schema_kwargs['include_data'] = schema_kwargs.get('include_data', tuple())
2525

2626
# collect sub-related_includes
2727
related_includes = {}
@@ -72,6 +72,7 @@ def compute_schema(schema_cls, default_kwargs, qs, include):
7272
related_schema_kwargs['context'] = default_kwargs['context']
7373
if isinstance(related_schema_cls, SchemaABC):
7474
related_schema_kwargs['many'] = related_schema_cls.many
75+
related_schema_kwargs['include_data'] = related_schema_cls.__dict__.get('include_data')
7576
related_schema_cls = related_schema_cls.__class__
7677
if isinstance(related_schema_cls, str):
7778
related_schema_cls = class_registry.get_class(related_schema_cls)

tests/test_sqlalchemy_data_layer.py

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class Person(base):
119119
)
120120

121121
computers_owned = relationship("Computer")
122+
address = relationship("Address", backref="person", uselist=False)
122123

123124
yield Person
124125

@@ -136,17 +137,35 @@ class Computer(base):
136137
yield Computer
137138

138139

140+
@pytest.fixture(scope="module")
141+
def address_model(base):
142+
class Address(base):
143+
144+
__tablename__ = "address"
145+
146+
id = Column(Integer, primary_key=True)
147+
street = Column(String)
148+
city = Column(String)
149+
state = Column(String)
150+
zip = Column(String)
151+
person_id = Column(Integer, ForeignKey("person.person_id"))
152+
153+
yield Address
154+
155+
139156
@pytest.fixture(scope="module")
140157
def engine(
141158
person_tag_model, person_single_tag_model, person_model,
142-
computer_model, string_json_attribute_person_model
159+
computer_model, string_json_attribute_person_model,
160+
address_model
143161
):
144162
engine = create_engine("sqlite:///:memory:")
145163
person_tag_model.metadata.create_all(engine)
146164
person_single_tag_model.metadata.create_all(engine)
147165
person_model.metadata.create_all(engine)
148166
computer_model.metadata.create_all(engine)
149167
string_json_attribute_person_model.metadata.create_all(engine)
168+
address_model.metadata.create_all(engine)
150169
return engine
151170

152171

@@ -189,6 +208,17 @@ def computer(session, computer_model):
189208
session_.commit()
190209

191210

211+
@pytest.fixture()
212+
def address(session, address_model):
213+
address_ = address_model(state='NYC')
214+
session_ = session
215+
session_.add(address_)
216+
session_.commit()
217+
yield address_
218+
session_.delete(address_)
219+
session_.commit()
220+
221+
192222
@pytest.fixture(scope="module")
193223
def dummy_decorator():
194224
def deco(f):
@@ -237,6 +267,29 @@ class AddressSchema(MarshmallowSchema):
237267
yield AddressSchema
238268

239269

270+
@pytest.fixture(scope="module")
271+
def person_address_schema():
272+
class PersonAddressSchema(Schema):
273+
class Meta:
274+
type_ = "address"
275+
276+
id = fields.Str(dump_only=True)
277+
street = fields.String()
278+
city = fields.String()
279+
state = fields.String()
280+
zip = fields.String()
281+
282+
person = Relationship(
283+
related_view="api.person_detail",
284+
related_view_kwargs={"person_id": "<person.person_id>"},
285+
schema="PersonSchema",
286+
id_field="person_id",
287+
type_="person",
288+
)
289+
290+
yield PersonAddressSchema
291+
292+
240293
@pytest.fixture(scope="module")
241294
def string_json_attribute_person_schema(address_schema):
242295
class StringJsonAttributePersonSchema(Schema):
@@ -255,7 +308,7 @@ class Meta:
255308

256309

257310
@pytest.fixture(scope="module")
258-
def person_schema(person_tag_schema, person_single_tag_schema):
311+
def person_schema(person_tag_schema, person_single_tag_schema, person_address_schema):
259312
class PersonSchema(Schema):
260313
class Meta:
261314
type_ = "person"
@@ -284,6 +337,11 @@ class Meta:
284337
many=True,
285338
)
286339

340+
address = Relationship(
341+
schema="PersonAddressSchema",
342+
type_="address",
343+
)
344+
287345
yield PersonSchema
288346

289347

@@ -920,6 +978,22 @@ def test_get_relationship_single_empty(session, client, register_routes, compute
920978
assert response.status_code == 200
921979

922980

981+
def test_get_include_multiple(session, client, register_routes, computer, person, address):
982+
session_ = session
983+
person.address = address
984+
computer.person = person
985+
session_.commit()
986+
987+
with client:
988+
response = client.get(
989+
"/computers/" + str(computer.id) + "?include=owner.computers,owner.address", content_type="application/vnd.api+json"
990+
)
991+
included = json.loads(response.data)['included']
992+
types = {item['type'] for item in included}
993+
assert {'person', 'computer', 'address'} == types
994+
assert response.status_code == 200
995+
996+
923997
def test_issue_49(session, client, register_routes, person, person_2):
924998
with client:
925999
for p in [person, person_2]:

0 commit comments

Comments
 (0)