I'll discuss about the model level translation flow that I worked on during my internship at Aasaanjobs. We implemented a hybrid approach to achieve translation of content in Django, partly static and partly model based.So, for static content ( on the templates ), I used native localisation provided by Django. The documentation is pretty straight forward. I used the linting toolDjango locale middleware has a hierarchical order of figuring out the locale in the context. I used the cookie based locale detection, which suited our purpose best. The default cookie tag for locale in Django is 'django_language'.The dynamic ( model based ) content was a challenge to translate. So I prepped a separate model that would contain the translation from all the models in every app of the project.
class Translation(models.Model): app_name = models.CharField(max_length=40) model_name = models.CharField(max_length=40) field_name = models.CharField(max_length=40) LANGUAGES = ( ('hi', 'Hindi'), ('mar', 'Marathi'), ) language = models.CharField(choices=LANGUAGES, max_length=9) audio = models.FileField(null=True,blank=True) translated_val = models.TextField(max_length=5000) entity_id = models.IntegerField(max_length=10) approved = models.BooleanField(default=False)
And to detect the translations in this above model, I wrote a TranslationMixin which was a child class to Models.model in django and overrode the __saveattr__ function.
class TranslationMixin(models.Model): def __setattr__(self, key, value): self.__dict__[key] = value if (key in self._meta.trans and value is not None and value is not ''): try: transobjs = Translation.objects.filter(approved=True,app_name=self._meta.app_label,model_name=self._meta.model_name,field_name=key,entity_id=self.id) for objs in transobjs: fieldName = key+"__"+objs.language self.__dict__[fieldName]=objs.translated_val except ObjectDoesNotExist: pass return self class Meta: abstract=TrueOnce this was done, we were almost all set to go, but we needed a listener for this translationmixin; So I for every model that we needed to fetch translation for, I added a Meta Trans tag to the fields. This ensured that the fields would be dynamically be looked up in the translation model. This is the overall conceptual schema of this approach. Thanks for reading :)