1

背景: 私は gae-boilerplate の主要な貢献者の 1 人です。gae-boilerplate は、ユーザーが webapp2 と最新機能を使用して Google アプリ エンジンで開発をすぐに開始できるようにするオープン ソースのボイラープレート プロジェクトです。私が取り組んだ最新の機能は、Babel と gaepytz を使用した i18n であり、以下に説明する問題が存在します。

問題: 翻訳は gettext で機能していますが、ハンドラーと wtforms クラスで生成されたフォーム エラー メッセージの翻訳には、私が知る限り、lazy_gettext が必要です。handlers.py を呼び出すと、Lazy_gettext が機能しませんfrom webapp2_extras.i18n import lazy_gettext as _。ページの読み込み時に、以下の致命的なエラー メッセージが表示されます。Babel Lazy プロキシ オブジェクトが作成されたように見えますが、ローカライズされた文字列をレンダリングするために呼び出されてから、Google アプリ エンジン サーバー コードの json シリアライザーに渡されません。私はbabelサイト、webapp2のドキュメント(もっと徹底したい)、他のフレームワーク、そしていくつかのGoogleコードを見てきましたが、私が欠けているものを理解することができませんでした.

エラーメッセージ:

Traceback (most recent call last):
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1536, in __call__
  rv = self.handle_exception(request, response, e)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1530, in __call__
  rv = self.router.dispatch(request, response)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1278, in default_dispatcher
  return route.handler_adapter(request, response)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1102, in __call__
  return handler.dispatch()
File "H:\jesse\python_dev\workspace\gae-boilerplate\lib\basehandler.py", line 54, in dispatch
  self.session_store.save_sessions(self.response)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\sessions.py", line 420, in save_sessions
  session.save_session(response)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\sessions.py", line 205, in save_session
  response, self.name, dict(self.session), **self.session_args)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\sessions.py", line 423, in save_secure_cookie
  value = self.serializer.serialize(name, value)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\securecookie.py", line 47, in serialize
  value = self._encode(value)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\securecookie.py", line 92, in _encode
  return json.b64encode(value)
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\json.py", line 84, in b64encode
  return base64.b64encode(encode(value, *args, **kwargs))
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\json.py", line 55, in encode
  return json.dumps(value, *args, **kwargs).replace("</", "<\\/")
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\__init__.py", line 272, in dumps
  use_decimal=use_decimal, **kw).encode(obj)
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 216, in encode
  chunks = list(chunks)
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 485, in _iterencode
  for chunk in _iterencode_dict(o, _current_indent_level):
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 459, in _iterencode_dict
  for chunk in chunks:
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 380, in _iterencode_list
  for chunk in chunks:
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 380, in _iterencode_list
  for chunk in chunks:
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 495, in _iterencode
  o = _default(o)
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 190, in default
  raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <babel.support.LazyProxy object at 0x00000000084E81F8> is not JSON serializable

環境の詳細: python、webapp2、babel などのバージョンに関するすべての詳細は、github.com/coto/ gae-boilerplate の readmeまで下にスクロールすると見つかります。最新の Google アプリ エンジン SDK 1.7.0 を実行しています

再現方法

  1. https://github.com/coto/gae-boilerplateからコードをダウンロードします
  2. from webapp2_extras.i18n import gettext as _web/handlers.py を次のように置き換えますfrom webapp2_extras.i18n import lazy_gettext as _
  3. アプリ エンジン開発サーバーを使用して実行します (手順はhttps://developers.google.com/appengine/docs/python/tools/devserverにあります) 。
  4. サインアップするか、ログインしてからログアウトします (localhost:8080/logout/)。ログアウトすると、ログアウトしたことを示すフラッシュ メッセージが生成され、lazy_gettext でラップされたメッセージを使用してログアウト ハンドラでエラーが生成されるため、エラーが発生します。

このプロジェクトと webapp2 の他のユーザーの助けになることは間違いありません。また、github のコードに目を通しておけば、ベスト プラクティスのヒントが得られます。ありがとうございました!

4

2 に答える 2

2

Babel には LazyProxy というカスタム クラスがあります。これは基本的に関数をラップするだけで、関数の戻り値が本当に必要な場合にのみ呼び出します。プロキシは可能な限り透過的にしようとしますが、simplejson が実際のクラス オブジェクトをチェックし、そこで失敗すると想定しています。

simplejson がプロトコルを使用して、インスタンスのシリアル化可能なバージョンを不明なクラスに要求するかどうかはわかりません (その後、LazyProxy でそれを実装できます)。

何らかの方法でライブラリを変更できる場合は、LazyProxy インスタンス用のカスタム シリアライザーも作成できます (これは非常に単純なはずです)。別のオプションは、LazyProxy インスタンスを見つけ、「proxy.value」を使用してプロキシされた値を取得することです (これは json シリアル化可能であると想定しています)。

于 2012-07-23T19:20:06.070 に答える
2

これは本当に古いですが、他の誰かが同じ問題を抱えている可能性があります。

Lazy gettext は後で翻訳プロセスをラップするため、実際の文字列ではなく、異なるタイプのオブジェクトになります。一部のjsonライブラリは、json化しようとしている式のタイプをチェックするため、例外が発生します。これを修正するには、Unicode ビルトインを使用して翻訳をトリガーできます。

元。

a = lazy_gettext("wololoh")
jsonify({'msg': a}) # this will throw an exception
jsonify({'msg': unicode(a)}) # this should work correctly

役に立つことを願っています

于 2014-07-09T18:35:20.240 に答える