2012-12-22 11 views
5

Ich habe Methode wie diese, und wie Json zurückgeben möchten, aber es schreibt, dass Beiträge Objekt nicht Json serializable: SFlask Jsonify mongoengine Abfrage

def show_results_async(text): 
    query = { '$or':[{'title':{'$regex':text}},{'author':{'$regex':text}} ]} 
    posts = Posts.objects(__raw__=(query)) 
    return jsonify(result = posts) 
+0

warum ist es '__raw __ = (Abfrage)'? meinst du "__raw __ = (query,)" oder "__raw __ = query"? –

Antwort

3

tl, dr: Es gibt keine integrierte Funktion Das konvertiert ein MongoEngine-Dokument in JSON. Du musst also deine eigenen schreiben.

In views.py:

def show_results_async(text): 
    query = { '$or':[{'title':{'$regex':text}},{'author':{'$regex':text}} ]} 
    posts = Posts.objects(__raw__=(query)) 
    return jsonify(result=posts.to_dict()) 

In post.py hinzu:

def to_dict(self): 
    return helper.mongo_to_dict(self) 

In helper.py:

def mongo_to_dict(obj): 
    return_data = [] 

    if isinstance(obj, Document): 
     return_data.append(("id",str(obj.id))) 

    for field_name in obj._fields: 

     if field_name in ("id",): 
      continue 

     data = obj._data[field_name] 

     if isinstance(obj._fields[field_name], DateTimeField): 
      return_data.append((field_name, str(data.isoformat()))) 
     elif isinstance(obj._fields[field_name], StringField): 
      return_data.append((field_name, str(data))) 
     elif isinstance(obj._fields[field_name], FloatField): 
      return_data.append((field_name, float(data))) 
     elif isinstance(obj._fields[field_name], IntField): 
      return_data.append((field_name, int(data))) 
     elif isinstance(obj._fields[field_name], ListField): 
      return_data.append((field_name, data)) 
     elif isinstance(obj._fields[field_name], EmbeddedDocumentField): 
      return_data.append((field_name, mongo_to_dict(data))) 

    return dict(return_data) 

Ein paar Anmerkungen:

  • Wenn Ihr Dokument zusätzliche Feldtypen enthält, müssen Sie die obige Hilfsfunktion erweitern.
  • Die obige Hilfsmethode wurde von Thomas' answer to a question inspiriert. Zusätzliche Funktionalität umfasst: rekursiv EmbeddedDocuments drucken und die ID des Dokuments enthalten.
+0

'my_document.to_json()' konvertiert ein MongoEngine-Dokument in JSON. Es funktioniert nicht, 'jsonify()' das JSON obwohl. Ich habe 'json.loads()' verwendet, um es in ein dict umzuwandeln und dann 'jsonify()' it zurückzugeben, obwohl es wahrscheinlich einen besseren Weg gibt. – Josh

11

Sie können Mongoengine Built-in-Methode verwenden: to_json(). Beispiel darüber, können Sie wie folgt verwenden:

def show_results_async(text): 
    query = { '$or':[{'title':{'$regex':text}},{'author':{'$regex':text}} ]} 
    posts = Posts.objects(__raw__=(query)) 
    return jsonify(result = posts.to_json()) 
+0

Sagt das Backslash-Escape nicht, da es doppelt Json-ified ist? Ich musste etwas tun wie 'jsonify (result = [json.loads (post.to_json()) für den Post in Posts.objects])'. – Josh

1

Dies funktioniert, obwohl ich weiß nicht, ob es der effizienteste Weg ist:

import json 

@app.route('/api/my-objects/') 
def get_objects(): 
    all_objects = [json.loads(o.to_json()) for o in MyObject.objects] 

    return jsonify({"my_objects": all_objects})