Django кастомная миграция с добавлением установочных данных

118 0

Иногда случаются ситуации когда данные в базе проекта уже есть и их надо связать с новой моделью, причем обязательной связью один ко многим.

Можно конечно временно обозначить связывающее поле ForeignKey как blank=True и заполнить после того как в новой модели появятся данные, а потом убрать blank=True.

Но это куча лишних действий и две миграции вместо одной.

Можно сделать тоже самое одной миграцией с добавлением в новую модель первой записи.

Для этого надо выполнить следующие шаги:

1. Делаем новую модель и связь к ней из существующей модели с данными:

class NewModel(models.Model):
    field_1 = models.CharField('field_1', max_length=100)
    field_2 = models.CharField('field_2', max_length=100)
    ...
class OldModel(models.Model):
    ...
    new_model = models.ForeignKey(NewModel,
                                 verbose_name='new_model',
                                 on_delete=models.CASCADE)
    ...

2. Делаем миграции командой ./manage.py makemigrations. Когда миграции предложат внести данные в поле связи по умолчанию new_model, внесем 1 - как id первой записи в модели NewModel.

3. Изменяем автоматически сгенерированную миграцию следующим образом:

    3.1. В названии файла миграции меняем auto на custom

    3.2. В файле миграции добавляем код:

def add_to_newmodel(apps, schema_editor):
    '''
    Добавление данных в новую модель
    '''
    new_model = apps.get_model("<Название приложения>", "NewModel")
    result = new_model.objects.create(
        field_1='Field_1 content',
        field_2='Field_2 content'
    )

class Migration(migrations.Migration):
    ...
    operations = [
        migrations.CreateModel(
            name='NewModel',
            ...
        ),
        # Добавляем данные после создания модели NewModel
        migrations.RunPython(add_to_newmodel,
                             reverse_code=migrations.RunPython.noop),
        ...
    ]

Вот и все.

В результате получим миграцию которая:

  • Создает новую модель;
  • Создает одну запись в новой модели;
  • Привязывает все существующие записи старой модели к единственной записи новой модели.

Комментарии

Контактные данные

 Россия, г. Москва
INFODATA