.. _modeltranslation_migration:

Migrating from django-modeltranslation
======================================

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

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

#. Add ``modeltrans`` to your ``INSTALLED_APPS``

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

#. Copy the setting ``AVAILABLE_LANGUAGES`` to ``MODELTRANS_AVAILABLE_LANGUAGES``.

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


    # translation.py
    from modeltranslation.translator import translator, TranslationOptions
    from .models import Blog

    class BlogTranslationOptions(TranslationOptions):
        fields = ('name', 'title', )

    translator.register(Blog, BlogTranslationOptions)

#. Run ``./manage.py makemigrations <apps>``. This will create the
   migration adding the ``i18n``-fields required by django-modeltrans. Apply
   them with ``./manage.py migrate``

#. 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>``.

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

#. 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

#. Run ``./manage.py makemigrations <apps>``. This will create migrations that remove the fields generated by
   django-modeltranslationfrom your registered models.

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

#. Update your code:

   - Use  the ``<field>_i18n`` field in places where you would use ``<field>`` with django-modeltranslation.
     Less magic, but `explicit is better than implicit <https://www.python.org/dev/peps/pep-0020/>`_!
   - 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.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)
