2013-07-13 5 views
10

Ich habe das Flask-Beispiel Minitwit gegabelt, um mit MongoDB zu arbeiten, und es funktionierte gut auf Flask 0.9, aber nach dem Upgrade auf 0.10. 1 Ich erhalte den Fehler im Titel, wenn ich mich anmelde, wenn ich versuche, die Sitzungs-ID festzulegen.Getting 'TypeError: ObjectId (' 'ist nicht JSON serialisierbar' bei Verwendung von Flask 0.10.1

Es scheint, dass es changes in Flask 0.10.1 bezogen auf json gab.

Code-Snippet:

user = db.minitwit.user.find_one({'username': request.form['username']}) 
session['_id'] = user['_id'] 

Voll Code in meinem github Repo.

Im Grunde genommen habe ich die Flask-Session-ID auf die _id des Benutzers von MongoDB gesetzt.

Ich versuchte die ersten beiden Lösung von diesem SO question ohne Erfolg.

Nun, tun Sitzung [ ‚_ id‘] = str (user [ ‚_ id‘]) wird der Fehlermeldung los und ich bin richtig auf die Timeline-Seite umgeleitet, aber ich bin nicht wirklich eingeloggt.

Wie kann ich das beheben?

EDIT: Kopieren/Einfügen des Zurückverfolgungs: http://pastebin.com/qa0AL1fk

Danke.

Antwort

12

EDIT vorbei: Noch einfacher Fix. Sie müssen nicht einmal JSON-Kodierung/Dekodierung durchführen.

Speichern Sie die Sitzung [ '_ id'] als String:

user = db.minitwit.user.find_one({'username': request.form['username']}) 
session['_id'] = str(user['_id']) 

Und dann überall Sie etwas mit der Sitzung tun wollen [ '_ id'] Sie haben es zu wickeln mit ObjectId() so Es wird als ObjectId-Objekt an MongoDB übergeben.

if '_id' in session: 
    g.user = db.minitwit.user.find_one({'_id': session['_id']}) 

zu:

if '_id' in session: 
    g.user = db.minitwit.user.find_one({'_id': ObjectId(session['_id'])}) 

Sie können für das Update auf meinem github repo die volle diff sehen.

Wenn jemand wissen möchte, warum die "TypeError: ObjectId ('') ist nicht JSON serializable '" Problem "in Flask 0.10.1 erschien, ist es, weil sie die Art und Weise geändert haben, wie Sitzungen gespeichert werden. Sie werden jetzt als JSON gespeichert. Da das '_id'-Objekt in MongoDB kein Standard-JSON ist, konnte das Sitzungstoken nicht serialisiert werden, was zu TypeError führte. Lesen Sie über die Änderung hier: http://flask.pocoo.org/docs/upgrading/#upgrading-to-010

9

JSON unterstützt standardmäßig nur eine begrenzte Anzahl von Objekttypen zur Serialisierung (Kodierung/Dekodierung). Sie könnten den Python-JSON-Decoder/-Codierer jedoch erweitern, um mit dieser Situation umzugehen.

In Bezug auf die Codieren eines Objekts, das auf ObjectID enthält, zum Beispiel, wenn ObjectIDs Client-Seite erstellt werden, die entlang bis zu einem gewissen warten Server übergeben werden, versuchen:

import json 
from bson.objectid import ObjectId 

class Encoder(json.JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, ObjectId): 
      return str(obj) 
     else: 
      return obj 

Dann im Code, bevor die Daten an Client drücken -> Server laufen:

json.dumps(obj, cls=Encoder) 

Seite Server, wenn wir wir es zu tun mit mongo docs (Dictionary-Objekt mit einem '_id' key) kennen, können wir einen json Decoder Haken definieren wie folgt:

def decoder(dct): 
    for k, v in dct.items(): 
     if '_id' in dct: 
      try: 
       dct['_id'] = ObjectId(dct['_id']) 
      except: 
       pass 
     return dct 

und nennt es einen Anruf wie die Verwendung von folgenden:

doc = json.loads(in_doc, object_hook=decoder) 

Sie werden wahrscheinlich diesen Code ein wenig anpassen müssen, aber für den einfachen Fall von

0

Dies ist, wie ich vor kurzem den Fehler behoben haben

@app.route('/') 
def home(): 
    docs = [] 
    for doc in db.person.find(): 
     doc.pop('_id') 
     docs.append(doc) 
    return jsonify(docs) 
0

toString wandelt sie in der Zeichenfolge und das kann zu Sitzung gespeichert:

session['_id'] = user['_id'].toString() 

alternative session['_id'] = str(user['_id'])

Das oben erwähnte reparierte den Fehler für mich.

Verwandte Themen