Заставьте Flask Зефир NestedSchema работать по моему маршруту API - PullRequest
1 голос
/ 05 марта 2020

Я делаю APi, используя Flask, SQLAlchemy и Marshmallow.

Модель определена, и база данных заполнена данными и при попадании в представление. Я получаю все поля JSON content от NonProfitSchema.

class NonprofitSchema(ma.ModelSchema):
    class Meta:
        model = Nonprofit

        # To specialize fields something like so
        fields = ('id', 'name', 'ein', 'ico', 'street', 'city', 'state', 'zipcode', 'group', 'subsection', 'affiliation', 'classification', 'ruling',
 'deductability', 'foundation', 'activity', 'organization', 'status', 'tax_period', 'asset_cd','income_cd', 'filing_req_cd', 'pf_filing_req_cd',
 'acct_pd', 'asset_amt', 'income_amt', 'revenue_amt', 'ntee', 'sort_name', 'activity_full')

Я пытался создать из этого новую схему и вернуть только подмножество данных с таким значением ниже

class AddressSchema(NonProfitSchema):

    from marshmallow import fields 
    address = fields.Nested(NonprofitSchema(only=("street", "city", "state", "zipcode",)))  

В моем файле view.py маршруты были настроены так:

@api_blueprint.route("/api/orgs/id/<int:id>/", methods=["GET"]) def get_org_by_id(id):
    org = Nonprofit.query.get(id)
    return npschema.jsonify(org)

@api_blueprint.route("/api/orgs/address/<int:id>/", methods=["GET"]) def get_org_by_id_address(id):
    org = Nonprofit.query.get(id)
    return addyschema.jsonify(org)

Однако при доступе к ним в браузере. Они оба возвращают одну и ту же вещь, то есть всю модель базы данных NonprofitSchema

Я полагаю, что невозможно сделать подмножества данных со Схемой, верно?

Ответы [ 3 ]

1 голос
/ 05 марта 2020

Кроме того, вы можете подключить эту логику c прямо к шагу jsonify

org = Nonprofit.query.get(id)
only_these_fields = ["street", "city", "state", "zipcode"]
return addyschema.jsonify({key: value for key, value in org.items() if key in only_these_fields}
0 голосов
/ 14 марта 2020

Я должен обновить ответ, с которым я пошел. Хотя я и пользователь c8999 c 3f964f64 в основном думали об одном и том же, и это действительно будет работать. В моем случае, «jsonify» для объекта не будет работать, так как в его примере я построил отдельную функцию, так как нет атрибута items. Так с фильтром, который использует атрибут get следующим образом:

def jsonfilter(obj, attrlist):

    resp = {}
    for attr in attrlist:
        resp[attr] = getattr(obj,attr)
    return resp

Затем изменив функцию так, чтобы она использовалась:

@api_blueprint.route("/api/orgs/id/<int:id>/address", methods=["GET"])
def get_org_address_by_id(id):
    org = Nonprofit.query.get(id)
    only_these_fields = ["id", "ein", "name", "street", "city", "state", "zipcode"]
    return jsonify(jsonfilter(org, only_these_fields))

Я смог заставить ее работать.

Альтернативный и гораздо более простой способ после просмотра документации Flask и Flask -Marshmallow состоит в простом создании экземпляра нового объекта класса модели с переданными полями.

@api_blueprint.route("/api/orgs/id/<int:id>/address", methods=["GET"])
def get_org_address_by_id(id):
    org = Nonprofit.query.get(id)
    only_these_fields = ["id", "ein", "name", "street", "city", "state", "zipcode"]
    addyschema = NonprofitSchema(fields=only_these_fields)
    return addyschema.jsonify(org)

Я выбрал против этого метода, потому что я предпочитаю использовать только один отдельный объект класса, и вызов метода фильтра чувствует себя лучше.

0 голосов
/ 06 марта 2020

У меня нет всей картины, но я нахожу странным вкладывать родительскую схему в дочерний.

А как насчет этого (не проверено)?

class AddressSchema(NonProfitSchema):

    class Meta:
        fields = ("street", "city", "state", "zipcode",)
...