如何在 Django models 中使用多语言 (i18n) 的简单方法

在我们的博客中, 记录了我们在开发过程中所使用的技术和遇到的问题, 希望作为其他开发和设计者的一个学习交流平台.

如何在 Django models 中使用多语言 (i18n) 的简单方法


本篇介绍一个在django model中使用多语言支持的快速方法, 该方法通过建立自定义的template tag 选取model中重复的语言field来达到多语言显示的目的.

假设我们有这样一个models.py, 某一个model中包含多个重复的field, 每个重复的field都是用来保存其对应的显示语言:

    class MyObject(models.Model):
        name = models.CharField(max_length=50)
        title_en = models.CharField(max_length=50)
        title_es = models.CharField(max_length=100)
        title_fr = models.CharField(max_length=100)
        description_en = models.CharField(max_length=100)
        description_es = models.CharField(max_length=100)
        description_fr = models.CharField(max_length=100)

    class MyOtherObject(models.Model):
        name = models.CharField(max_length=50)
        content_en = models.CharField(max_length=200)
        content_es = models.CharField(max_length=200)
        content_fr = models.CharField(max_length=200)

注意, 我们将下划线和语言代码作为后缀放在对应的field后面, 这将作为一个语言的查找标记.

然后我们在settings.py中添加需要翻译的field名:

    TRANSLATION_FIELDS = ('title', 'description', 'content')

在项目目录中添加templatetags目录(不要忘了怎家__init__.py), 并在其中建立lazy_tags.py:

    from django import template
    from settings import TRANSLATION_FIELDS

    register = template.Library()

    class LocalizedContent(template.Node):
        def __init__(self, model, language_code):
            self.model = model
            self.lang = language_code

        def render(self, context):
            model = template.resolve_variable(self.model, context)
            lang = template.resolve_variable(self.lang, context)
            for f in TRANSLATION_FIELDS:
                try:
                    setattr(model, f, getattr(model, '%s_%s' % (f, lang)))
                except AttributeError:
                    pass
            return ''

    @register.tag(name='get_localized_content')
    def get_localized_content(parser, token):
        bits = list(token.split_contents())
        if len(bits) != 3:
            raise template.TemplateSyntaxError("'get_localized_content' tag takes exactly 2 arguments")
        return LocalizedContent(model=bits[1], language_code=bits[2])

为了在template中使用自定义的tag, 我们首先载入:

    {% load lazy_tags %}

然后使用自定义tag, 传入object和语言代码, 取的翻译. 比如西班牙语:

    {% get_localized_content object 'es' %}

此时, 如果没有语言代码传入, 那么无法使用obj.description调用某一个语言field. 所以我们配合django.core.context_processors.request, context processor一起使用:

    TEMPLATE_CONTEXT_PROCESSORS = (
            ...
    'django.core.context_processors.request',
    )

我们就能在template中这样使用:

    {% get_localized_content object request.LANGUAGE_CODE %}

原文链接: http://weiguda.com/blog/53/