【问题标题】:Modifying a Flask-Restless result array修改 Flask-Restless 结果数组
【发布时间】:2017-11-14 19:28:45
【问题描述】:

我有这样的事情:

{
  "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]
                   })

【问题讨论】:

    标签: python flask flask-sqlalchemy flask-restless


    【解决方案1】:

    我认为您需要使用后处理器,因为您需要在将 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
    }
    

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回答。我试过了,但没有用。我将在原始帖子中编辑我的views.py 代码,看看你是否能看到任何错误。此外,说 results['userdetails'] = .... 的部分给了我一个错误,说这是不可能的。我尝试将其更改为仅返回结果 ['userdetails'] 并且错误消失了,但它仍然不起作用。事实上,我尝试打印并没有到达那里(到 detail_sort)。
    • @plasmy 你得到什么错误?尝试首先在结果中设置关键 userdetails 的值,然后返回它。我还没有测试我的代码。
    • 是的,我确实尝试过,但没有出现错误。问题是它仍然没有做我想要的。
    • @plasmy 你能粘贴错误的堆栈跟踪吗?
    • Traceback (most recent call last): File "run.py", line 1, in &lt;module&gt; from medinv import app File "/Users/myname/PycharmProjects/MedInvAPI/medinv/__init__.py", line 10, in &lt;module&gt; from medinv.User.views import blueprint File "/Users/myname/PycharmProjects/MedInvAPI/medinv/User/views.py", line 15 return results['userdetails'] = {item['detail_name']: item['detail'] for item in results['userdetails']} ^ SyntaxError: invalid syntax 我已经编辑了代码来展示我是如何修复这个错误的。使用该代码,我没有收到错误。
    猜你喜欢
    • 2013-03-04
    • 2015-10-14
    • 1970-01-01
    • 2014-08-02
    • 2013-10-16
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多