2014-09-30 10 views
8

Sto usando estensioni https://pythonhosted.org/Flask-Babel/ per la localizzazione.Errore serializzabile Flask JSON a causa di flacone babele

classe form di base

#!/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 

il mio modulo di classe

#!/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"))]) 

mio avviso

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

Getta questo errore "TypeError: è richiesto il contenuto lu'Post' non è JSON serializzabile".

quando rimuovo la localizzazione da _ ("Titolo del post") per "Post Title" funziona, ma quando uso babele non funziona

Penso che sia su Unicode. perché ho fatto questo cambiamento _ ("Post Title"). encode ("utf-8") funziona. Ma questa soluzione non è efficace. Come posso risolvere il problema.

risposta

11

Il problema è che il messaggio di errore è un oggetto _LazyString restituito da lazy_gettext, non una stringa. Normalmente, questo non sarebbe un problema perché visualizzarlo in un modello chiamerebbe str() su di esso, facendolo valutare la traduzione. Tuttavia, si stanno raccogliendo gli oggetti in error_list e quindi li si passa a jsonify e json non ha serializzatore per questi oggetti.

È necessario dire al serializzatore JSON di Flask come gestire questi oggetti. Scrivi un serializzatore personalizzato quindi assegnalo a app.json_encoder. soluzione

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

Cambio di davidism per

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

di lavorare su Python 2 invece.

+0

Questo non è corretto per una serie di motivi. Dovresti sempre restituire del testo ('str' in Py3,' unicode' in Py2). Sicuramente non codificare/decodificare il testo, basta chiamare 'unicode' per Py2. Usa il modulo compat di Flask, come ho modificato nella mia risposta, per essere compatibile con entrambi. – davidism

Problemi correlati