Пишу
API на
Flask-RESTplus с использованием
Flask-Marshmallow. Возникает необходимость добавлять некоторую информацию к ответу сформированному через
schema.dump(some_data). Например, у меня есть модель
Flask-SQLAlchemy:
class User(mixins.PaginatedAPIMixin, db.Model):
id = db.Column(db.Integer, primary_key=True, unique=True)
username = db.Column(db.String(45), nullable=False, unique=True)
password_hash = db.Column(db.String(128), unique=True)
Так же есть ресурс:
Resource@api.route('/', endpoint='users')
class UsersResource(Resource):
@api.param('page', description='Page number :int:')
@api.param('per_page', description='Items per page :int:')
def get(self):
args = parse_get_args(page=int, per_page=int)
users = User.get_paginated(User.query, self, args['page'], args['per_page'])
schema = UsersSchema(many=True)
dumped_data = schema.dump(users['items']).data
dumped_data.append({'_links': users['_links'], '_meta': users['_meta']})
return schema.jsonify(dumped_data)
UsersSchema - это
ModelSchema из
Flask-Marshmallow(страницы указаны для примера, так как пагинация идет в
mixins.PaginatedAPIMixin):
class UsersSchema(ma.ModelSchema):
class Meta:
model = User
fields = ('id', 'username')
Так вот, в методе
get() ресурса
UsersResource, в переменной
users в качестве результата вызова метода
get_paginated() модели, хранится вот какой словарь (
items - объекты пользователей):
users{'items': items,
'_meta': {
'page': 1,
'per_page': 20,
'total_pages': 1,
'total_items': 2
},
'_links': {
'self': 'api/v1/users/?page=1&per_page=20',
'next': None,
'prev': None
}}
Загвоздка в том, что хоть
dumped_data.append({'_links': users['_links'], '_meta': users['_meta']}) и добавляет словарь в список, но последующий вызов
schema.jsonify(dumped_data) рубит в нем все поля не указанные в
ModelSchema ... В итоге получается вот что:
Как-то так[
{
"id": 1,
"username": "spam"
},
{
"id": 2,
"username": "egg"
},
{}
]
А хотелось бы вот что:
Хотелось бы так[
"items": [
{
"id": 1,
"username": "spam"
},
{
"id": 2,
"username": "egg"
}
],
"_links": {
"self": "api/v1/users/?page=1&per_page=20"
},
"_meta": {
"page": 1,
"per_page": 20,
"total_pages": 1,
"total_items": 2
},
]
Через
self.declared_fields.update(additional_fields) в конструкторе
ModelSchema пробовал, отображает только если добавляемое новое поле уже содержится в кортеже
fields...
Пока единственным решением является использовать не
schema.jsonify(), а
flask.jsonify(), тогда все отдается нормально, но мне кажется что это как-то криво.