GAE Python 优化:Django 筛选器用于语言支持

一个 web 应用开发者遇到了一个与语言支持相关的过滤问题。当他将其发布到 GAE 时,它不断提示 CPU 使用率过高。他认为问题出自他用于支持的筛选器。他在模板中使用了这种方式:

<h1>{{ "collection.header"|translate:lang }}</h1>

其筛选器代码如下:

import re
from google.appengine.ext import webapp
from util import dictionary

register = webapp.template.create_template_register()

def translate(key, lang):
    d = dictionary.GetDictionaryKey(lang, key)
    if d == False:
        return "no key for " + key
    else: 
        return d.value

register.filter(translate)

他对于 Python 不太熟悉,无法发现其中的问题所在,并且不确定这样的方法是否是完全错误的。

他希望寻找一种方法来处理语言支持。用户需要能够通过管理页面更新文本元素。目前,所有文本元素都存储在一个数据库模型中,并使用一个筛选器根据语言来获取正确的键。

经过大量的测试,他仍然无法让它足够好地工作。在发布后,他仍然在日志中收到有关 CPU 使用率过高的错误消息。一个典型的页面大约有 30-50 个文本元素,而根据日志,每次页面加载大约使用 1500ms(API 为 900ms)。他开始认为这可能不是最好的方法。

他还尝试同时使用 Memcache 和索引来解决 CPU 使用问题。这稍微有点帮助。应该同时使用 Memcache 和手动添加索引吗?

他的筛选器代码如下:

import re
from google.appengine.ext import webapp
from google.appengine.api import memcache

from util import dictionary

register = webapp.template.create_template_register()

def translate(key, lang):
    re = "no key for " + key

    data = memcache.get("dictionary" + lang)

    if data is None:
        data = dictionary.GetDictionaryKey(lang)
        memcache.add("dictionary" + lang, data, 60)

    if key in data:
        return data[key]
    else:   
        return "no key for " + key


register.filter(translate)

util.dictionary 代码如下:

from google.appengine.ext import db

class DictionaryEntries(db.Model):
    lang = db.StringProperty()
    dkey = db.StringProperty()
    value = db.TextProperty()
    params = db.StringProperty()

    @property
    def itemid(self):
        return self.key().id()

def GetDictionaryKey(lang):
    entries = DictionaryEntries.all().filter("lang = ", lang)
    if entries.count() > 0:
        langObj = {}
        for entry in entries:
            langObj[entry.dkey] = entry.value

        return langObj 
    else:
        return False

2、解决方案

第一个答案提供了一个简洁的解决方案,指出问题在于对 entries.count()for entry in entries 的昂贵查询。他建议使用 Memcache 来缓存查询结果,并对查询进行轻量化。

from utils import dictionary

def GetDictionaryKey(lang, key):
    chache_key = 'dictionary_%s_%s' % (lang, key)
    data = memcache.get(cache_key)
    if not data:
         entry = DictionaryEntries.all().filter("lang = ", lang).filter("value =", key).get()
         if entry:
             data = memcache.add(cache_key, entry.value, 60)
         else:
             data = 'no result for %s' % key
    return data

def translate(key, lang):
     return dictionary.GetDictionaryKey(lang, key)

第二个答案则建议使用标准的 gettext 方法,它是 Python 和 Django 中广泛应用的一种国际化方法。这个方法使用 .po 文件来存储翻译,并在运行时动态加载。

{% load i18n %}
<h1>{% trans "Header of my Collection" %}</h1>

这两个答案都提供了有效的解决方案,可以帮助开发者优化 GAE Python 应用程序的语言支持,并降低 CPU 使用率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值