Skip to content
This repository was archived by the owner on Jun 6, 2024. It is now read-only.
This repository was archived by the owner on Jun 6, 2024. It is now read-only.

should flask.Schema.check_relationships honor data_key? #320

Open
@femto113

Description

@femto113

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions