2014-09-30 5 views
8

Ich verwende https://pythonhosted.org/Flask-Babel/ Erweiterung für die Lokalisierung.Flask JSON serializable Fehler wegen der Flasche babel

Basisformularklasse

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

from app import app 
from flask.ext.wtf import Form 

class BaseForm(Form): 

    @property 
    def error_list(self): 
     _errors = [] 

     for fieldName, errorMessages in self.errors.iteritems(): 
      for err in errorMessages: 
       _errors.append(err) 

     return _errors 

meine Form Klasse

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

from flask import g 

from wtforms import StringField, TextField, PasswordField # BooleanField 
import wtforms.validators as validators 
from flask.ext.babel import lazy_gettext as _ 
from flask.ext.babel import npgettext as _n 

from app.base_forms import * 

class PostForm(BaseForm): 
    post_title = StringField(_("Post Title"), [validators.Required(message=_("Post title is required")) ]) 
    post_content = StringField(_("Post Content"), [ validators.Required(message=_("Post content is required"))]) 

meiner Ansicht

... 
viewJsonData["error_list"] = form.error_list 
return jsonify(**viewJsonData) 

Es diesen Fehler „Typeerror wirft: lu'Post Inhalt‚erforderlich ist, ist nicht JSON serialisierbar ".

wenn ich entfernen Lokalisierung von _ („Post-Titel“) auf „Post-Titel“ es funktioniert, aber wenn ich babel verwenden es funktioniert nicht

Ich denke, es über Unicode ist. weil ich das geändert habe _ ("Beitrag Titel"). encode ("utf-8") es funktioniert. Aber diese Lösung ist nicht effektiv. Wie kann ich das Problem lösen?

Antwort

11

Das Problem ist, dass Ihre Fehlermeldung ein _LazyString Objekt ist, das von lazy_gettext zurückgegeben wird, keine Zeichenfolge. Normalerweise wäre dies kein Problem, da die Anzeige in einer Vorlage str() darauf anwendete, wodurch die Übersetzung ausgewertet wurde. Sie sammeln jedoch die Objekte in error_list und übergeben sie dann an jsonify, und Json verfügt über keinen Serializer für diese Objekte.

Sie müssen dem JSON-Serializer von Flask mitteilen, wie mit diesen Objekten verfahren wird. Schreiben Sie einen benutzerdefinierten Serializer und weisen Sie ihn dann app.json_encoder zu.

from flask._compat import text_type 
from flask.json import JSONEncoder as BaseEncoder 
from speaklater import _LazyString 

class JSONEncoder(BaseEncoder): 
    def default(self, o): 
     if isinstance(o, _LazyString): 
      return text_type(o) 

     return BaseEncoder.default(self, o) 

app.json_encoder = JSONEncoder 
0

ändern davidism Lösung zu

return str(o.encode('UTF-8')) 

2 statt auf Python zu arbeiten.

+0

Dies ist aus einer Reihe von Gründen falsch. Du solltest immer Text zurückgeben ('str' in Py3,' unicode' in Py2). Den Code nicht doppelt kodieren/dekodieren, einfach "unicode" für Py2 aufrufen. Verwenden Sie Flasks compat-Modul, wie ich in meiner Antwort bearbeitet habe, um mit beiden kompatibel zu sein. – davidism