Django - Перенос поля из дочерней модели в родительскую - Ручной перенос для наследования приводит к `FieldError`.
Короткая версия
Я пытаюсь запустить пользовательскую миграцию (через RunPython
), которая включает унаследованную модель, скажем Restaurant
. Однако в на FieldError
возникает исключение Restaurant.objects.all()
, указывающее, что унаследованное поле не может быть разрешено. Действительно, модель, возвращаемая apps.get_model("myapp", "Restaurant")
, как ни странно, не наследуется от родительского класса.
Более длинная версия
Context
Рассмотрим многотабличное наследование в Django, где модель, скажем Restaurant(address, serves_pizza)
, наследуется от родительской модели, скажем Place(name)
. Поля для обеих моделей указаны в скобках. Цель - передать определенное поле Restaurant
, скажем address
, родительскому классу Place
. Одна из задач состоит в том, чтобы сохранить данные, передавая их с помощью специализированной операции миграции. Одна идея, которая кажется мне довольно простой, заключается в следующем
- first create an intermediate field
address_place
inPlace
, - then, manually move the data from
Restaurant.address
toRestaurant.address_place
(viamigrations.RunPython
) - finally remove
address
field and renameaddress_place
intoaddress
Сфокусировавшись на 2. вот как выглядит пользовательский код, вызываемый RunPython
:
def transfer_address_from_restaurant_to_place(apps, schema_editor):
Restaurant = apps.get_model("myapp", "Restaurant")
for restau in Restaurant.objects.all():
restau.address_place = restau.address
restau.save()
FieldError
, неожиданная ошибка
Однако при выполнении соответствующей миграции в FieldError
возникает исключение for restau in Restaurant.objects.all()
, которое выглядит следующим образом:
FieldError: Cannot resolve keyword 'name' into field. Choices are: address, serves_pizza
И все же Restaurant
должен иметь доступ к полям родительского класса Place
, то есть name
и address_place
. На самом деле, если мы рассмотрим модель Restaurant
, возвращаемую apps.get_model
, то увидим, что она вообще не наследуется от родительской модели Place
, а просто от базы models.Model
...
Hence
- чем это можно объяснить, а именно тем, что
apps.get_model
не сохраняет наследование? - и как с этим бороться? или какой другой подход можно использовать, чтобы обойти эту проблему и получить поле
address
в родительском классе?