Иногда случаются ситуации когда данные в базе проекта уже есть и их надо связать с новой моделью, причем обязательной связью один ко многим.
Можно конечно временно обозначить связывающее поле 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),
...
]
Вот и все.
В результате получим миграцию которая:
- Создает новую модель;
- Создает одну запись в новой модели;
- Привязывает все существующие записи старой модели к единственной записи новой модели.
Комментарии