2013-06-04 16 views
8

Sto creando un'API da un database MongoDB usando Flask e hanno il seguente codice:Flask display JSON in un modo pulito

app.route('/<major>/') 
def major_res(major): 
    course_list = list(client.db.course_col.find({"major" : (major.encode("utf8",  "ignore").upper())})) 
    return json.dumps(course_list, sort_keys=True, indent=4, default=json_util.default) 

che quando viene chiamato con CSCI importanti ritorni:

[{"corso": "CSCI052", "descrizione": "Fondamenti dell'informatica: una solida base per la programmazione funzionale, l'astrazione procedurale e dei dati, la ricorsione e la risoluzione di problemi Applicazioni in settori chiave dell'informatica, inclusi algoritmi e complessità , architettura e organizzazione dei computer, linguaggi di programmazione, automi finiti e computa bilità. Questo corso ha lo stesso ruolo di HM 60 come prerequisito per i corsi di informatica della divisione superiore in uno qualsiasi dei college di Claremont. Prerequisito: 51. "," istruttore ":" Bull, Everett L. ,, Jr. "," nome ":" Fondamenti di Informatica "," numero ": 52," scuola ":" PO "}]

come faccio a restituire questo dizionario in modo che ogni chiave e valore sono sulla loro propria linea

+0

per questo usato '' argomento indent' json.dimps', ma è già in possesso. Questo non è un JSON minimizzato, perché hai spazi dopo le virgole e ':'. Quindi come si ottiene questo risultato (nel browser, registro/stampa, wget)? Probabilmente è necessario usare 'return Response (, mimetype = 'application/json')' o 'flask.jsonofy' con argomento' indent'. – tbicr

risposta

13

Flask fornisce jsonify() come vantaggio:?

app.route('/<major>/') 
def major_res(major): 
    course_list = list(client.db.course_col.find({"major": major.encode('utf8', 'ignore').upper() })) 
    return flask.jsonify(**course_list) 

Ciò restituirà i kwargs di jsonify come ben risposta JSON formattata e, a differenza del tuo codice, invierà l'intestazione Content-Type corretta: application/json.

Tuttavia, prendere atto di ciò che i documenti su questo:

la risposta di questa funzione sarà abbastanza stampato se non è stato richiesto con X-Requested-With: XMLHttpRequest per semplificare il debug meno che il parametro di configurazione JSONIFY_PRETTYPRINT_REGULAR è impostato su false.

Ciò significa che le risposte Ajax riceveranno sempre JSON non prettyprinted (dal momento che la politica di origine stesso rende impossibile impostata X-Requested-With). Ma immagino che questo non sarà un grosso problema dato che il consumo di JSON per JS non dovrebbe essere necessariamente formattato (sono solo dati extra da inviare sul filo).

Se vuoi utilizzare ancora json.dumps() (non abbastanza stampate), è possibile inviare il corretto tipo MIME restituendo un flask.Response, tuttavia, si dovrebbe prendere in considerazione the security implications of this:

app.route('/<major>/') 
def major_res(major): 
    course_list = list(client.db.course_col.find({"major": major.encode('utf8', 'ignore').upper() })) 
    return flask.Response(response=json.dumps(course_list), status=200, mimetype='application/json') 

Per maggiori informazioni sulla differenza :

+0

come da Flask 0.13 L'intestazione "X-Requested-With" viene ignorata e la stampa carina verrà forzata solo in modalità di debug (se JSONIFY_PRETTYPRINT_REGULAR non è impostato), aggiornare la risposta. –

0

Se per qualche motivo è necessario over-ride flask.jsonify (l'aggiunta di un encoder personalizzato per esempio) è possibile farlo con il seguente metodo che implementa l'@phpmycoder fix di sicurezza menzionato:

from json import dumps 
from flask import make_response 

def jsonify(status=200, indent=4, sort_keys=True, **kwargs): 
    response = make_response(dumps(dict(**kwargs), indent=indent, sort_keys=sort_keys)) 
    response.headers['Content-Type'] = 'application/json; charset=utf-8' 
    response.headers['mimetype'] = 'application/json' 
    response.status_code = status 
    return response 

app.route('/<major>/') 
def major_res(major): 
course = client.db.course_col.find({"major": (major.encode("utf8", "ignore").upper())}) 
return jsonify(**course) 

app.route('/test/') 
def test(): 
return jsonify(indent=2, sort_keys=False, result="This is just a test") 

Risposta:

{ 
    "course": "CSCI052", 
    "description": "Fundamentals of Computer Science. A solid foundation in functional programming, procedural and data abstraction, recursion and problem-solving. Applications to key areas of computer science, including algorithms and complexity, computer architecture and organization, programming languages, finite automata and computability. This course serves the same role as HM 60 as a prerequisite for upper-division computer science courses at any of the Claremont Colleges. Prerequisite: 51.", 
    "instructor": "Bull, Everett L.,, Jr.", 
    "name": " Fundamentals of Computer Science", 
    "number": 52, 
    "school": "PO" 
} 

Vedere la mia other answer per un esempio utilizzando un codificatore jSON personalizzato

+0

Poiché viene restituito un solo corso, non è necessario un elenco. Se hai un'altra rotta che restituisce più corsi, puoi eseguire questa operazione: 'courses = query.that.returns.list' e' return jsonify (courses = courses) ' – reubano

Problemi correlati