开发者

Content translation in Django, compatible with South

I'm looking for a solution to have translatable database fields in Django, and the solution needs to be compatible with South.

I already found django-transmeta and transdb. Only the latter seems to be compatible wit开发者_开发技巧h South, but I'm not sure about that. Also, transdb values don't look nice in the database (something the customer actually cares about).

Has anybody worked with such a combination? I'm not particaluary focussed on South, but it seems to be the way to go for schema migration in Django.


I suppose that tho two apps use custom fields and South complains about that. Here you can read about how to enable south for those custom fields: http://south.aeracode.org/docs/customfields.html.

Two relevant links:

  • THE DJANGO ORM AND MULTILINGUAL DATABASE CONTENTS (A talk on Djangocon 2011)
  • http://djangopackages.com/grids/g/i18n/


Because we did know that the number of languages will never change, we switched to having fields for each language and a simple mechanism for automatically reading the correct field for the current language. Our implementation is used like this:

class Question(models.Model):
    __metaclass__ = LocalizeModelBase

    text_de = models.TextField(verbose_name=_(u"question text (german)"))
    text_en = models.TextField(verbose_name=_(u"question text (english)"))
    text = Translate

Question().text then automatically returns the correct field, based on the current language with a fallback to the default language.

The implementation behind it should be pretty much self-explaining:

from django.db.models.base import ModelBase
from django.utils.translation import get_language
from django.conf import settings

__all__ = ('Translate', 'LocalizeModelBase')

# a dummy placeholder object
Translate = object()


class LocalizeModelBase(ModelBase):
    """This meta-class provides automatically translated content properties. Set
    a model field to `Translate` and it will automatically return the property
    with the name of the current language. E.g. if there is a normal member
    `text_de`, a member `text = Translate` and the current language is `de`, then
    an object will return the content of `text_de` when it is asked for the value
    of `text`.
    """
    def __new__(metacls, classname, bases, classDict):
        # find all classDict entries that point to `Translate`
        for key in classDict.keys():
            if classDict[key] is Translate:
                # replace them with a getter that uses the current language
                classDict[key] = make_property(key)
        return super(LocalizeModelBase, metacls).__new__(metacls, classname, bases, classDict)


def make_property(k):
    """Creates a new property that implements the automatic translation
    described above. Every use of `Translate` in a class definition will be
    replaces with a property returned by this function."""
    def pget(self):
        try:
            # try to return the attribute for the current language
            return getattr(self, "%s_%s" % (k, get_language()))
        except AttributeError:
            # use the default language if the current language is not available
            return getattr(self, "%s_%s" % (k, settings.LANGUAGE_CODE))
    return property(pget)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜