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.")