should flask.Schema.check_relationships honor data_key? #320
Description
This problem just came up for me. I've got models that represent a person, and the person can have one or more "tickets", and each ticket may have an associated "pass" (think like going to a convention where the pass is the thing around your neck, the ticket is a more abstract thing you buy). Python veterans will immediately spot the problem: pass
is a reserved word. Simplified code:
from marshmallow_jsonapi.flask import Relationship, Schema
class Person(Schema):
... other person fields ...
tickets = Relationship(many=True, schema=Ticket, ...)
class Ticket(Schema):
... other ticket fields ...
# because it's a reserved word, this field is named pass_ but we set the data_key so it shows up as pass
pass_ = Relationship(schema=Pass, data_key='pass')
class Pass(Schema):
... pass fields ...
The problem comes when trying to include the pass
relationship, e.g. Person(include_data=['tickets.pass'])
generates an error
marshmallow_jsonapi/schema.py, line 78, in __init__
self.check_relations(self.include_data)",
marshmallow_jsonapi/schema.py, line 117, in check_relations
field.schema.check_relations(fields[1:])
marshmallow_jsonapi/schema.py, line 105, in check_relations
raise ValueError(f'Unknown field "{local_field}"')
ValueError: Unknown field "pass"
This happens because this code looks in fields and pass
isn't there (in fields it's named pass_
)
local_field = fields[0]
if local_field not in self.fields:
raise ValueError(f'Unknown field "{local_field}"')
Replacing that first line with
local_field = next((n for n, f in self.fields.items() if f.data_key == fields[0]), fields[0])
seems to work--that just says use a field whose data_key matches the value from the include (if there is one). I'm guessing the vast majority of the time the field and the data_key are the same so this doesn't matter, but shouldn't includes always use the data_key since that's the only name the rest of the world knows the relationship by?