2017-06-13 2 views
2

J'ai quelque chose comme ceci:Modification d'un tableau de résultat Flask-Restless

{ 
    "id": 1, 
    "username": "plasmy", 
    "userdetails": [ 
    { 
     "detail": "A Name", 
     "detail_name": "Full Name", 
     "id": 1, 
     "user_id": 1 
    }, 
    { 
     "detail": "[email protected]", 
     "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 
    } 
    ] 
} 

Cela vient à la suite de l'utilisation Flask_Restless et SQLAlchemy. Il y a une table pour les utilisateurs et une table pour les détails de l'utilisateur, qui sont placés dans la partie détails de l'utilisateur de ce JSON. Ce que je veux faire est de trouver un moyen dans lequel les données peuvent ressembler à ceci:

{ 
    "id": 1, 
    "username": "plasmy", 
    "userdetails": { 
     "Full Name": "A Name", 
     "Email": "[email protected]", 
     "Address": "An Address", 
     "Phone Number": "A Phone Number" 
    } 
} 

Voyez comment je l'ai enlevé les cartes d'identité et je le champ « detail_name » comme la clé et « détail » en tant que valeur. J'ai essayé d'utiliser des préprocesseurs mais ils n'ont pas fonctionné ou peut-être que je les utilise mal. Je mets le préprocesseur dans la table "enfant".

C'est ce que j'ai essayé de faire (mais ne fonctionne pas):

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

J'ai essayé GET_COLLECTION, GET_SINGLE et GET_MANY. Toute aide à ce sujet sera grandement appréciée.

MISE À JOUR: Voici le nouveau code J'ai essayé fonderont sur la réponse

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

Répondre

2

Je pense que vous devez utiliser postproccessors puisque vous devez modifier la réponse JSON avant de l'envoyer au client.

OK, j'ai reproduit votre problème. Maintenant ça marche. Voici mon code:

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='[email protected]', 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) 

Notez que vous devez utiliser GET_MANY et regardez comment detail_sort est mis en œuvre.

Sans utiliser postprocessor la réponse est comme ceci:

{ 
    "num_results": 1, 
    "objects": [ 
    { 
     "id": 1, 
     "userdetails": [ 
     { 
      "detail": "A name", 
      "detail_name": "Full Name", 
      "id": 1, 
      "user_id": 1 
     }, 
     { 
      "detail": "[email protected]", 
      "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 
} 

Avec postprocessor la réponse ressemble à ceci:

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

Hope this helps.

+0

Nous vous remercions de votre réponse. J'ai essayé ça et ça n'a pas marché. Je vais modifier mon code views.py dans le post original pour voir si vous pouvez voir quelque chose de mal. De plus, la partie qui dit results ['userdetails'] = .... me donne une erreur en disant que ce n'est pas possible. J'ai essayé de le changer un peu en ne renvoyant que les résultats ['userdetails'] et l'erreur disparaît mais ça ne marche toujours pas. En fait j'ai essayé de faire une impression et ça n'arrive pas (à detail_sort). – plasmy

+0

@plasmy Que recevez-vous comme erreur? Essayez d'abord de définir la valeur des détails de l'utilisateur clé dans les résultats, puis renvoyez-la. Je n'ai pas testé mon code. – Nurjan

+0

Oui, j'ai essayé et l'erreur n'apparaît pas. Le problème est que ça ne fait toujours pas ce que je veux. – plasmy