5

要約は非常に紛らわしいかもしれませんが、より簡潔に定式化する方法がわかりません。

私が持っているモデル:

class Movie(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(
    imdb_data = db.relationship('IMDBData', uselist=False)

class IMDBData(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255))
    rating = db.Column(db.Float)
    movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'))

Flask-Restful フィールドを使用して、次のように応答をマーシャリングしています。

imdb_data_fields = {
    'id': fields.Integer,
    'title': fields.String,
    'rating': fields.Float
}

movie_fields = {
    'id': fields.Integer,
    'title': fields.String
}

class MovieListAPI(Resource):
    def __init__(self):
        self.parser = reqparse.RequestParser()
        super(MovieListAPI, self).__init__()

    def get(self):
        self.parser.add_argument('imdb_data', type=str, location='args')
        args = self.parser.parse_args()

        m_fields = copy.copy(movie_fields)

        # TODO: Return empty object if movie.imdb_data = None
        if args['imdb_data']:
            m_fields['imdb_data'] = fields.Nested(imdb_data_fields)

        movies = Movie.query.all()
        return {'movies': marshal(movies, m_fields)}

imdb_dataムービーに対応するレコードがない場合、つまりMovie.query.filter_by(id=123).first().imdb_data = None、そのムービーのオブジェクトは次のようにマーシャリングされます。

{
    "id": 1302, 
    "imdb_data": {
        "id": 0, 
        "rating": null, 
        "title": null
    },     
    "title": "F 63 9 Love Sickness"
}

代わりに、次のような応答が必要です。

{
    "id": 1302, 
    "imdb_data": {},     
    "title": "F 63 9 Love Sickness"
}

1つの映画を(IDで)返すときにこれをハックする方法を知っています:

if args['imdb_data']:
    if movie.imdb_data:
        m_fields['imdb_data'] = fields.Nested(imdb_data_fields)
    else:
        m_fields['imdb_data'] = fields.Nested({})

しかし、映画のリストについてはどうすればよいでしょうか。おそらく、自分で配列を調べて手動で変更することもできますが、もっと効率的な方法があるはずです。

4

3 に答える 3

4

これは、次のようにカスタム フィールドを作成することで実現できます。

class NestedWithEmpty(Nested):
    """
    Allows returning an empty dictionary if marshaled value is None
    """
    def __init__(self, nested, allow_empty=False, **kwargs):
        self.allow_empty = allow_empty
        super(NestedWithEmpty, self).__init__(nested, **kwargs)

    def output(self, key, obj):
        value = get_value(key if self.attribute is None else self.attribute, obj)
        if value is None:
            if self.allow_null:
                return None
            elif self.allow_empty:
                return {}

        return marshal(value, self.nested)

次に、それを使用してオブジェクトをマーシャリングしますallow_empty=True:

m_fields['imdb_data'] = NestedWithEmpty(imdb_data_fields, allow_empty=True)

この機能を使ってプル リクエストも作成しました: https://github.com/twilio/flask-restful/pull/328

于 2014-11-13T06:35:26.760 に答える
2

PR #328 (@Andriy に感謝) を読み、それに従って、私の修正はデフォルトの引数を追加することでした

foo['bar'] = fields.Nested(nested_fields, default={})

ドキュメントでは明らかではありませんでした。

于 2018-04-05T09:59:21.927 に答える