修改Flask-Restless结果数组

时间:2017-06-13 06:58:34

标签: python flask flask-sqlalchemy flask-restless

我有这样的事情:

{
  "id": 1, 
  "username": "plasmy",
  "userdetails": [
    {
      "detail": "A Name", 
      "detail_name": "Full Name", 
      "id": 1, 
      "user_id": 1
    }, 
    {
      "detail": "an@email.com", 
      "detail_name": "Email", 
      "id": 2, 
      "user_id": 1
    }, 
    {
      "detail": "An Address", 
      "detail_name": "Address", 
      "id": 3, 
      "user_id": 1
    }, 
    {
      "detail": "999-999-9999", 
      "detail_name": "Phone Number", 
      "id": 4, 
      "user_id": 1
    }
  ]
}

这是使用Flask_Restless和SQLAlchemy的结果。有一个用户表和一个userdetails表,它们放在该JSON的userdetails部分。我想要做的是,找到一种数据看起来像这样的方式:

{
  "id": 1, 
  "username": "plasmy",
  "userdetails": {
      "Full Name": "A Name",
      "Email": "an@email.com",
      "Address": "An Address",
      "Phone Number": "A Phone Number"
    }
}

看看我是如何删除id的,我使用字段“detail_name”作为键,“detail”作为值。我尝试使用预处理器,但它们没有用,或者我使用它们错了。我把预处理器放在“子”表中。

这是我尝试做的(但没有奏效):

def detail_sort(results):
    return {'user_details': results['userdetails']}


manager.create_api(User, methods=['GET', 'POST'])
manager.create_api(UserDetails, methods=['GET', 'POST'],
                   preprocessors={
                       'GET_COLLECTION': [detail_sort]
                   })

我尝试了GET_COLLECTION,GET_SINGLE和GET_MANY。任何有关这方面的帮助将不胜感激。

更新:这是我根据答案尝试的新代码

from flask import Blueprint
from medinv import manager
from medinv.User.models import User, UserDetails

blueprint = Blueprint('blueprint', __name__)


@blueprint.route('/')
@blueprint.route('/home')
def home():
    return "Welcome."


def detail_sort(results):
    print(results)
    results['userdetails'] = {item['detail_name']: item['detail'] for item in results['userdetails']}
    return results['userdetails']


manager.create_api(User, methods=['GET', 'POST'])
manager.create_api(UserDetails, methods=['GET', 'POST'],
                   postprocessors={
                       'GET_COLLECTION': [detail_sort]
                   })

1 个答案:

答案 0 :(得分:3)

我认为您需要使用postproccessors,因为您需要在将json响应发送回客户端之前修改它。

好的,我转载了你的问题。现在它正在运作。这是我的代码:

import flask
import flask_sqlalchemy
import flask_restless

# Create the Flask application and the Flask-SQLAlchemy object.
app = flask.Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = flask_sqlalchemy.SQLAlchemy(app)


# Create your Flask-SQLALchemy models as usual but with the following
# restriction: they must have an __init__ method that accepts keyword
# arguments for all columns (the constructor in
# flask_sqlalchemy.SQLAlchemy.Model supplies such a method, so you
# don't need to declare a new one).

class User(db.Model):

    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String)
    userdetails = db.relationship('UserDetails', backref='User', lazy='dynamic')


class UserDetails(db.Model):

    __tablename__ = 'user_details'

    id = db.Column(db.Integer, primary_key=True)
    detail = db.Column(db.String)
    detail_name = db.Column(db.String)
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)

# Create the database tables.
db.create_all()

# Create the Flask-Restless API manager.
manager = flask_restless.APIManager(app, flask_sqlalchemy_db=db)

user = User(username='plasmy')
userdetail_0 = UserDetails(detail='A name', detail_name='Full Name' )
userdetail_1 = UserDetails(detail='an@email.com', detail_name='Email')
userdetail_2 = UserDetails(detail='An Address', detail_name='Address')
userdetail_3 = UserDetails(detail='999-999-9999', detail_name='Phone Number')


user.userdetails.append(userdetail_0)
user.userdetails.append(userdetail_1)
user.userdetails.append(userdetail_2)
user.userdetails.append(userdetail_3)

db.session.add(user)
db.session.commit()

print('USER CREATED')

def detail_sort(result, **kw):
    print('detail_sort called')
    print(result)

    for entry in result['objects']:
        entry['userdetails'] = {item['detail_name']: item['detail'] for item in
                                entry['userdetails']}
    print('MODIFIED JSON: ', result)

# Create API endpoints, which will be available at /api/<tablename> by
# default. Allowed HTTP methods can be specified as well.
# manager.create_api(Person, methods=['GET', 'POST', 'DELETE'])
# manager.create_api(Article, methods=['GET'])

manager.create_api(User, methods=['GET', 'POST', 'DELETE'],
                   postprocessors={
                       'GET_MANY': [detail_sort]
                   })
manager.create_api(UserDetails, methods=['GET'], )

# start the flask loop
app.run(use_reloader=False)

请注意,您需要使用GET_MANY并查看detail_sort的实施方式。

不使用后处理器,响应如下:

{
  "num_results": 1, 
  "objects": [
    {
      "id": 1, 
      "userdetails": [
        {
          "detail": "A name", 
          "detail_name": "Full Name", 
          "id": 1, 
          "user_id": 1
        }, 
        {
          "detail": "an@email.com", 
          "detail_name": "Email", 
          "id": 2, 
          "user_id": 1
        }, 
        {
          "detail": "An Address", 
          "detail_name": "Address", 
          "id": 3, 
          "user_id": 1
        }, 
        {
          "detail": "999-999-9999", 
          "detail_name": "Phone Number", 
          "id": 4, 
          "user_id": 1
        }
      ], 
      "username": "plasmy"
    }
  ], 
  "page": 1, 
  "total_pages": 1
}

使用后处理器,响应如下所示:

{
  "num_results": 1, 
  "objects": [
    {
      "id": 1, 
      "userdetails": {
        "Address": "An Address", 
        "Email": "an@email.com", 
        "Full Name": "A name", 
        "Phone Number": "999-999-9999"
      }, 
      "username": "plasmy"
    }
  ], 
  "page": 1, 
  "total_pages": 1
}

希望这有帮助。