我可以在GAE上使用python 2.7和django.utils.translation吗?

2 投票
1 回答
626 浏览
提问于 2025-04-17 05:21

我在做本地化的时候用到了i18n,就像django那样,使用自定义的请求处理器来切换不同的语言。不过现在升级到Python 2.7后遇到了一些麻烦,因为它使用了来自django.utils.translation的cookie。在最糟糕的情况下,我可能需要从我们自定义的请求处理器转到其他系统来帮我们切换语言。你有没有什么建议来解决这个错误?django-language这个cookie还像以前那样可用吗?我还有哪些不依赖于django的本地化替代方案?比如Babel?我还能用我以前的.po和.mo文件吗?我应该使用其他的Cookie类吗?这是我的自定义请求处理器类:

from django.utils import translation

class I18NHandler(webapp.RequestHandler):   

    def initialize(self, request, response):
        webapp.RequestHandler.initialize(self, request, response)
        self.request.COOKIES = Cookies(self)
        self.request.META = os.environ
        self.reset_language()

    def reset_language(self):

        # Decide the language from Cookies/Headers

        language = translation.get_language_from_request(self.request)
        translation.activate(language)
        self.request.LANGUAGE_CODE = translation.get_language()

        # Set headers in response

        self.response.headers['Content-Language'] = \
            translation.get_language()


class Cookies(UserDict.DictMixin):

    def __init__(self, handler, **policy):
        self.response = handler.response
        self._in = handler.request.cookies
        self.policy = policy
        if 'secure' not in policy \
            and handler.request.environ.get('HTTPS', '').lower() \
            in ['on', 'true']:
            policy['secure'] = True
        self._out = {}

    def __getitem__(self, key):
        if key in self._out:
            return self._out[key]
        if key in self._in:
            return self._in[key]
        raise KeyError(key)

    def __setitem__(self, key, item):
        self._out[key] = item
        self.set_cookie(key, item, **self.policy)

    def __contains__(self, key):
        return key in self._in or key in self._out

    def keys(self):
        return self._in.keys() + self._out.keys()

    def __delitem__(self, key):
        if key in self._out:
            del self._out[key]
            self.unset_cookie(key)
        if key in self._in:
            del self._in[key]
            p = {}
            if 'path' in self.policy:
                p['path'] = self.policy['path']
            if 'domain' in self.policy:
                p['domain'] = self.policy['domain']
            self.delete_cookie(key, **p)

    # begin WebOb functions

    def set_cookie(
        self,
        key,
        value='',
        max_age=None,
        path='/',
        domain=None,
        secure=None,
        httponly=False,
        version=None,
        comment=None,
        ):
        """
        Set (add) a cookie for the response
        """

        cookies = BaseCookie()
        cookies[key] = value
        for (var_name, var_value) in [
            ('max-age', max_age),
            ('path', path),
            ('domain', domain),
            ('secure', secure),
            ('HttpOnly', httponly),
            ('version', version),
            ('comment', comment),
            ]:
            if var_value is not None and var_value is not False:
                cookies[key][var_name] = str(var_value)
            if max_age is not None:
                cookies[key]['expires'] = max_age
        header_value = cookies[key].output(header='').lstrip()
        self.response.headers._headers.append(('Set-Cookie',
                header_value))

    def delete_cookie(
        self,
        key,
        path='/',
        domain=None,
        ):
        """
        Delete a cookie from the client.  Note that path and domain must match
        how the cookie was originally set.
        This sets the cookie to the empty string, and max_age=0 so
        that it should expire immediately.
        """

        self.set_cookie(key, '', path=path, domain=domain, max_age=0)

    def unset_cookie(self, key):
        """
        Unset a cookie with the given name (remove it from the
        response).  If there are multiple cookies (e.g., two cookies
        with the same name and different paths or domains), all such
        cookies will be deleted.
        """

        existing = self.response.headers.get_all('Set-Cookie')
        if not existing:
            raise KeyError('No cookies at all have been set')
        del self.response.headers['Set-Cookie']
        found = False
        for header in existing:
            cookies = BaseCookie()
            cookies.load(header)
            if key in cookies:
                found = True
                del cookies[key]
            header = cookies.output(header='').lstrip()
            if header:
                self.response.headers.add('Set-Cookie', header)
        if not found:
            raise KeyError('No cookie has been set with the name %r'
                           % key)

错误追踪:

Traceback (most recent call last):
  File "/base/data/home/apps/s~montaoproject/main.354356023835363013/webapp2.py", line 545, in dispatch
    return method(*args, **kwargs)
  File "/base/data/home/apps/s~montaoproject/main.354356023835363013/i18n.py", line 781, in get
    cookie_django_language
  File "/base/data/home/apps/s~montaoproject/main.354356023835363013/util.py", line 65, in __setitem__
    self.set_cookie(key, item, **self.policy)
  File "/base/data/home/apps/s~montaoproject/main.354356023835363013/util.py", line 120, in set_cookie
    self.response.headers._headers.append(('Set-Cookie',
AttributeError: ResponseHeaders instance has no attribute '_headers'

提前感谢你的任何建议。

1 个回答

3

我觉得这是因为WebOb已经升级到了新的Python 2.7运行环境。

你应该使用:

res.headers.add('Set-Cookie', header_value)

正如webob的文档中所指出的那样。

请注意,webapp也被webapp2替代了。

撰写回答