Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Multi-lingual model in Django used for internationalizing content (See related posts)

The approach taken here gives each object (in this case a wiki Page) a language and a translation_of field. These two fields can be added to any model that wants to add content translations.

Pages are created in a default language. To translate a page, you create a new page and set the translation_of field to the page in the default language that you are translating.

A set of helper methods allow you to get the root version of the page (in the default language), all translations of a page, or a specific translation. These are useful for adding translation links.

   1  
   2  LANGUAGE_CHOICES = (
   3      ('en', 'English'),
   4      ('nl', 'Nederlands')
   5  )
   6  
   7  class Page(models.Model):
   8      language = models.CharField(maxlength=2, choices=LANGUAGE_CHOICES)
   9      title = models.CharField(maxlength=60)
  10      path = models.SlugField(prepopulate_from=('title',))
  11      translation_of = models.ForeignKey('self', related_name='translation_set', limit_choices_to = {'language' : settings.DEFAULT_LANGUAGE}, blank=True, null=True, help_text="Select which page this is a translation of. Don't set this for english pages.", validator_list = [local_models.validate_translation_of])
  12      content = models.TextField(blank=True)
  13  
  14      def get_root_translation(self):
  15          """Returns the root translation for this page.
  16          
  17          This page will be in the settings.DEFAULT_LANGUAGE."""
  18          if self.translation_of is None:
  19              return self
  20          else:
  21              return self.translation_of
  22  
  23      def get_translations(self):
  24          """Return all of the translations for this page."""
  25          # If I am the root translation, just return all of my translations.
  26          if self.translation_of is None:
  27              return self.translation_set.all()
  28          else:
  29              # If I am not the root, return the root translations, plus all of its
  30              # translations, minus myself.
  31              return Page.objects.filter(
  32                  models.Q(id=self.translation_of.id) | 
  33                  models.Q(translation_of=self.translation_of.id)).exclude(pk=self.id)
  34                  
  35      def get_translation(self, language):
  36          """Return a specific translation of this page."""
  37          if self.language == language:
  38              return self
  39          # If I am the root translation, search for translations of me in the given language
  40          elif self.translation_of is None:
  41              try:
  42                  return Page.objects.get(translation_of=self.id, language=language)
  43              except Page.DoesNotExist:
  44                  return None
  45          # Find the root page and the specific translation
  46          else:
  47              # If am not the root, find the root page with the given language,
  48              # otherwise find the page that is a translation of me in the given language
  49              return Page.objects.filter(
  50                  models.Q(id=self.translation_of.id) |
  51                  models.Q(translation_of=self.translation_of.id),
  52                  language=language)


In local_models.py there's this validator to check if the translation_of attribute was not set for pages in the default language:

   1  
   2  def validate_translation_of(field_data, all_data):
   3    if field_data is not None and len(str(field_data)) > 0 and all_data['language'] == settings.DEFAULT_LANGUAGE:
   4      raise validators.ValidationError("Do not set the translation for english pages.")

You need to create an account or log in to post comments to this site.


Click here to browse all 5556 code snippets

Related Posts