2015-10-19 1 views
2

Я пытаюсь удалить конкретную родительскую модель и скопировать некоторые ее поля непосредственно на дочерний элемент. Я несколько раз выполнял аналогичный процесс, прежде чем использовать Юг (одна и та же родительская модель для других детей), но с момента обновления до Django 1.7 он просто не играет в игру. Джанго дает следующее сообщение об ошибке во время migrate процесса:Миграции Django отказываются признать модель, которая больше не наследуется от старого родителя

FieldError: Local field <field_name> in class <child_model> clashes with field of similar name from base class <parent_model> 

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

Аналогичный вопрос has been asked here before, а принятое решение включает в себя создание новой модели, копирование данных на нее, замену существующей модели и копирование данных обратно. К сожалению, этот подход не будет работать в моем случае. Это установленная модель с многочисленными внешними ключами, указывающими на нее, которая будет потеряна, если исходные записи будут удалены.

The (упрощенный) подход, который я использовал при Юге:

  1. Удалить модель в качестве родителя и добавить новые поля к ребенку
  2. Добавить явное поле первичного ключа с тем же именем, что и старое авто *_ptr_id поле
  3. Run schemamigration и редактировать файл:

    • Удалить попытку Юга удалить и г ecreate в *_ptr поле
    • Добавьте пользовательскую логику, чтобы удалить ForeignKey-ность в *_ptr_id области и добавить PrimaryKey-Несс
  4. Используйте datamigration, чтобы захватить значение от старого родителя и добавить их в новых областях на ребенке

Это подход, который я надеялся, что буду достаточно легко адаптировать к родной миграции Django, и я получил (с некоторой настройкой) замена логика *_ptr_id поля происходит. Но Django не позволит мне добавлять новые поля. Я попытался следующий:

  • Удаление родительской модели и выполнять замену пользовательских *_ptr_id, миграция и добавление полей в качестве второй миграции.
  • Извлечение родительской модели и не редактирование файла вручную с помощью *_ptr_id, но удаление операций удаления/добавления Django и перенос с --fake.

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

У кого-нибудь еще была эта проблема и удалось обойти ее?

Edit:

Это, как представляется, вызвано bases аргументом CreateModel схемы работы класса листинга родительской модели, а также отсутствие операции согласования, чтобы обновить список. documentation for CreateModel перечисляет этот аргумент как необязательный, но есть ли побочные эффекты для ручного изменения этого значения в ранее примененной миграции?

ответ

0

После того, как эта проблема возникла в Django 1.11, я последовал за отредактированным советом и нашел начальный вызов CreateModel в моих файлах миграции. Комментируя строку bases=('{appname}.{modelname}',), и явно устанавливая первичный ключ моей модели как «id», повторный запуск makemigrations и migrate исправил эту проблему для меня.

Я не уверен, что изменение первичного ключа имеет отношение к решению, я просто выставляю переменные.

Другой вариант для людей, менее вложенных в их название модели (и данных): переименуйте его при удалении родителя. Обратите внимание, что, хотя это сработало для меня, переход к исходному имени модели в другой миграции ударил эту же «однажды дочернюю, всегда дочернюю» ошибку, так что вам все равно придется редактировать строку «base =» в ваших миграциях.

Благодарим oogles и Community!

+0

Да, после того, как я не нашел альтернативы и не получил ответа, я также закончил редактирование этой строки '' основы''. С тех пор я не заметил никаких негативных последствий. И поскольку я забыл вернуться и ответить на это как таковое, вы, сэр, просто заработали себе приемлемый ответ;). – oogles