Django Migrations ValueError: [] было объявлено с ленивой ссылкой на []

У меня довольно сложная архитектура проекта, включающая несколько приложений, модели которых содержат перекрестные ссылки.

Например, у меня есть модель billing.Premium, принадлежащая приложению billing, на которую ссылается другая модель с именем payments.PaymentJob через поле один к одному:

('premium', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='billing.Premium', verbose_name='premium'))

(Этот код взят из одной из миграций payment)

Но я дошел до того, что мне нужно переименовать billing.Premium в billing.PremiumInstallment, и тут начинается самое интересное: после рефакторинга моего кода, чтобы заменить имя модели, я пытаюсь django-admin makemigrations, это приводит к следующей ошибке:

ValueError: The field payments.PaymentJob.premium was declared with a lazy reference to 'billing.premium', but app 'billing' doesn't provide model 'premium'.

Похоже, моя миграция была нарушена, так как я переименовал модель внешнего приложения. Я не знаю, как это красиво исправить, я имею в виду создание некоторой миграции без ошибок, которая будет применяться при запуске django-admin migrate.

Есть идеи?


person Geoffrey R.    schedule 23.10.2017    source источник
comment
Я не очень разбираюсь в моделировании Django, но из ошибки видно, что вы переименовали модель, на которую ссылается другая, а затем измененные не переносятся, поскольку ссылка больше не найдена. Взгляните на это, так как ваша ошибка может быть решена с помощью правильных шагов на не простой архитектуре and-relationship-fields" title="Стратегия миграции django для переименования полей модели и отношений"> stackoverflow.com/questions/25091130/   -  person Carmine Tambascia    schedule 23.10.2017
comment
Я сделал это, но все модели находятся в одном приложении, а у меня есть две модели в двух отдельных приложениях, и я не могу правильно провести рефакторинг с помощью описанного метода...   -  person Geoffrey R.    schedule 23.10.2017


Ответы (1)


Согласно документам для операции RenameModel

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

Вы должны вручную создать миграцию и добавить к ней операцию RenameModel

class Migration(migrations.Migration):

    dependencies = [
        ('billing', 'xxxx_previous_migration'), 
    ]

    operations = [
        migrations.RenameModel('Premium', 'PremiumInstallment')
    ]
person Iain Shelvington    schedule 23.10.2017
comment
Нужно ли тогда редактировать другую миграцию, чтобы она указывала на billing.PremiumInstallment, а не на billing.Premium? Потому что теперь миграция немного глючит, поскольку указывает на модель, которой больше не существует. - person Geoffrey R.; 23.10.2017
comment
Я считаю, что лучше проверить все модели, которые зависят от той, которую вы переименовали. - person Carmine Tambascia; 23.10.2017
comment
Интересный момент: чтобы убедиться, что ваша ручная миграция учитывает ВСЕ изменения вашей модели, после создания и сохранения пользовательского файла миграции запустите python manage.py makemigrations. Это сделает миграцию со всеми изменениями, которые не учитывались вашей пользовательской миграцией. Хорошо для бухгалтерии и перепроверки. - person Sam Bobel; 23.10.2017