2014-09-30 150 views
8

我使用https://pythonhosted.org/Flask-Babel/擴展本地化。燒瓶JSON可序列化的錯誤,因爲燒瓶babel

基本形式類

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

我的表單類

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

我看來

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

它拋出這個錯誤「類型錯誤:lu'Post內容要求」不是JSON序列化」。

當我從_(「職位名稱」)刪除本地化「文章標題」它的工作,但是當我用巴貝爾它不工作

我認爲這是關於Unicode。因爲我做了這個改變_(「帖子標題」)。encode(「utf-8」)它的工作原理。但是這個解決方案並不有效。我該如何解決這個問題。

回答

11

問題是您的錯誤消息是由lazy_gettext返回的_LazyString對象,而不是字符串。通常情況下,這不是一個問題,因爲在模板中顯示它會調用str(),導致它評估翻譯。但是,您正在收集error_list中的對象,然後將它們傳遞給jsonify,並且json沒有這些對象的序列化程序。

您需要告訴Flask的JSON序列化程序如何處理這些對象。編寫一個自定義串行器,然後將其分配給app.json_encoder

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

變化davidism的解決

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

對Python的2工作,而不是。

+0

這是不正確的,原因很多。你應該總是返回文本(Py3中的'str',Py2中的'unicode')。絕對不要對文本進行雙重編碼/解碼,只需爲Py2調用'unicode'即可。使用Flask的compat模塊,因爲我在答案中編輯過,以便與兩者兼容。 – davidism 2017-02-24 14:55:53