Migrating from django-modeltranslation

This is how to migrate from django-modeltranslation (version 0.12.1) to django-modeltrans:

  1. Make sure you have a recent backup of your data available!

  2. Add modeltrans to your INSTALLED_APPS

  3. Make sure the default language for django-modeltranslation is equal to the language in LANGUAGE_CODE, which django-modeltrans will use.

  4. Copy the setting AVAILABLE_LANGUAGES to MODELTRANS_AVAILABLE_LANGUAGES.

  5. Add the TranslationField to the models you want to translate and keep the registrations for now. In order to prevent field name collisions, disable the virtual fields in django-modeltrans for now (virtual_fields=False):

    # models.py
    from django.contrib.postgres.indexes import GinIndex
    from django.db import models
    
    from modeltrans.fields import TranslationField
    
    class Blog(models.Model):
        title = models.CharField(max_length=255)
        body = models.TextField(null=True)
    
        # add this field, containing the TranslationOptions attributes as arguments:
        i18n = TranslationField(fields=('title', 'body'), virtual_fields=False)
    
        # add the GinIndex
        class Meta:
            indexes = [GinIndex(fields=["i18n"])]
    
    
    # translation.py
    from modeltranslation.translator import translator, TranslationOptions
    from .models import Blog
    
    class BlogTranslationOptions(TranslationOptions):
        fields = ('name', 'title', )
    
    translator.register(Blog, BlogTranslationOptions)
    
  6. Run ./manage.py makemigrations <apps>. This will create the migration adding the i18n-fields required by django-modeltrans. Apply them with ./manage.py migrate

  7. We need to create a migration to copy the values of the translated fields into the newly created i18n-field. django-modeltrans provides a management command to do that ./manage.py i18n_makemigrations <apps>.

  8. Run ./manage.py migrate to apply the generated data migrations. Your models with translated fields should have a populated i18n field after these migrations.

  9. Now, to remove django-modeltranslation:

    • Remove modeltranslation from INSTALLED_APPS.
    • Remove django-modeltranslation settings (DEFAULT_LANGUAGE, AVAILABLE_LANGUAGES) from your settings.py’s
    • Remove all translation.py files from your apps.
    • Remove the use of modeltranslation.admin.TranslationAdmin in your admin.py’s
  10. Run ./manage.py makemigrations <apps>. This will create migrations that remove the fields generated by django-modeltranslation from your registered models.

  11. Run ./manage.py migrate to actually apply the generated migrations. This will remove the django-modeltranslation fields and their content from your database.

  12. Update your code:

    • Remove virtual_fields=False from each TranslationField.

    • Use the <field>_i18n field in places where you would use <field> with django-modeltranslation. Less magic, but explicit is better than implicit!

    • Use <field>_<language> for the translated fields, just like your are used to.

    • If you use lookups containing translated fields from non-translated models, you should add MultilingualManager() to your models as a manager:

      from django.contrib.postgres.indexes import GinIndex
      from django.db import models
      
      from modeltrans.fields TranslationField
      from modeltrans.manager import MultilingualManager
      
      
      class Site(models.Model):
          title = models.CharField(max_length=100)
      
          # adding manager allows queries like Site.objects.filter(blog__title_i18n__contains='modeltrans')
          objects = MultilingualManager()
      
      
      class Blog(models.Model):
          title = models.CharField(max_length=100)
          body = models.TextField()
      
          i18n = TranslationField(fields=('title', 'body'))
          site = models.ForeignKey(Site)
      
          class Meta:
              indexes = [GinIndex(fields=["i18n"]]