<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Fdb's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Thu, 28 Aug 2008 13:09:17 GMT</pubDate>
    <description>DZone Snippets: Fdb's Code Snippets</description>
    <item>
      <title>Multi-lingual model in Django used for internationalizing content</title>
      <link>http://snippets.dzone.com/posts/show/2979</link>
      <description>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;LANGUAGE_CHOICES = (&lt;br /&gt;    ('en', 'English'),&lt;br /&gt;    ('nl', 'Nederlands')&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;class Page(models.Model):&lt;br /&gt;    language = models.CharField(maxlength=2, choices=LANGUAGE_CHOICES)&lt;br /&gt;    title = models.CharField(maxlength=60)&lt;br /&gt;    path = models.SlugField(prepopulate_from=('title',))&lt;br /&gt;    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])&lt;br /&gt;    content = models.TextField(blank=True)&lt;br /&gt;&lt;br /&gt;    def get_root_translation(self):&lt;br /&gt;        """Returns the root translation for this page.&lt;br /&gt;        &lt;br /&gt;        This page will be in the settings.DEFAULT_LANGUAGE."""&lt;br /&gt;        if self.translation_of is None:&lt;br /&gt;            return self&lt;br /&gt;        else:&lt;br /&gt;            return self.translation_of&lt;br /&gt;&lt;br /&gt;    def get_translations(self):&lt;br /&gt;        """Return all of the translations for this page."""&lt;br /&gt;        # If I am the root translation, just return all of my translations.&lt;br /&gt;        if self.translation_of is None:&lt;br /&gt;            return self.translation_set.all()&lt;br /&gt;        else:&lt;br /&gt;            # If I am not the root, return the root translations, plus all of its&lt;br /&gt;            # translations, minus myself.&lt;br /&gt;            return Page.objects.filter(&lt;br /&gt;                models.Q(id=self.translation_of.id) | &lt;br /&gt;                models.Q(translation_of=self.translation_of.id)).exclude(pk=self.id)&lt;br /&gt;                &lt;br /&gt;    def get_translation(self, language):&lt;br /&gt;        """Return a specific translation of this page."""&lt;br /&gt;        if self.language == language:&lt;br /&gt;            return self&lt;br /&gt;        # If I am the root translation, search for translations of me in the given language&lt;br /&gt;        elif self.translation_of is None:&lt;br /&gt;            try:&lt;br /&gt;                return Page.objects.get(translation_of=self.id, language=language)&lt;br /&gt;            except Page.DoesNotExist:&lt;br /&gt;                return None&lt;br /&gt;        # Find the root page and the specific translation&lt;br /&gt;        else:&lt;br /&gt;            # If am not the root, find the root page with the given language,&lt;br /&gt;            # otherwise find the page that is a translation of me in the given language&lt;br /&gt;            return Page.objects.filter(&lt;br /&gt;                models.Q(id=self.translation_of.id) |&lt;br /&gt;                models.Q(translation_of=self.translation_of.id),&lt;br /&gt;                language=language)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In local_models.py there's this validator to check if the translation_of attribute was not set for pages in the default language:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def validate_translation_of(field_data, all_data):&lt;br /&gt;  if field_data is not None and len(str(field_data)) &gt; 0 and all_data['language'] == settings.DEFAULT_LANGUAGE:&lt;br /&gt;    raise validators.ValidationError("Do not set the translation for english pages.")&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 08 Nov 2006 16:44:56 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2979</guid>
      <author>fdb (Frederik De Bleser)</author>
    </item>
  </channel>
</rss>
