Search code examples
pythondjangodjango-migrations

Apply a migration to Django Flatpage model


I would like to use the modeltranslation package in a Django application that uses the flatpages app.

I installed both, followed the model translation docs, and created a translation.py file, which I put in the main app (where all the global stuff lies), as I can't put it directly in the flat pages app (Django code is a requirement and is not committed to VCS).

# django/main/translation.py
from modeltranslation.translator import translator, TranslationOptions
from django.contrib.flatpages.models import FlatPage


class FlatPageTranslationOptions(TranslationOptions):
    fields = ('title', 'content')


translator.register(FlatPage, FlatPageTranslationOptions)

Then I ran python manage.py makemigrations, and it created a migration file in the flatpages app /usr/local/lib/python3.8/site-packages/django/contrib/flatpages/migrations/0002_auto_20211118_1558.py. It would be again in the Django code, so I tried to simply move it to the main app at django/main/migrations/0002_flatpages_translations.py (there is already an unrelated 0001_initial.py migration, which has no dependencies):

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('flatpages', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='flatpage',
            name='content_en',
            field=models.TextField(blank=True, null=True, verbose_name='content'),
        ),
        migrations.AddField(
            model_name='flatpage',
            name='content_fr',
            field=models.TextField(blank=True, null=True, verbose_name='content'),
        ),
        migrations.AddField(
            model_name='flatpage',
            name='title_en',
            field=models.CharField(max_length=200, null=True, verbose_name='title'),
        ),
        migrations.AddField(
            model_name='flatpage',
            name='title_fr',
            field=models.CharField(max_length=200, null=True, verbose_name='title'),
        ),
    ]

And... when I finally try to run the migration (python manage.py migrate), I got this error:

CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0001_initial, 0002_flatpages_translations in main).
To fix them run 'python manage.py makemigrations --merge'

I tried the --merge flag, but got another error: ValueError: Could not find common ancestor of ['0001_initial', '0002_flatpages_translations'] Is it possible to achieve what I want to do?


Solution

  • Found a solution, so I post it here if someone has the same problem. According Django documentation, you can specify the package where migration modules can be found on a per-app basis.

    So, in settings.py, add:

    MIGRATION_MODULES = {
        'flatpages': 'main.migrations.flatpages',
    }
    

    Then move the migration file 0002_flatpages_translations.py in django/main/migrations/flatpages/. In the case of the flatpages app, you will also need to copy the 0001_initial.py migration file from the flatpage app, inside this directory.

    And you're good, Django now searches the migrations for the flatpages app in your new directory.