精简版
我正在尝试运行RunPython
涉及继承模型的自定义迁移(通过),例如Restaurant
。但是FieldError
,在 处引发异常Restaurant.objects.all()
,指定无法解析继承的字段。实际上,oddly 返回的模型apps.get_model("myapp", "Restaurant")
不是从父类继承的。
更长的版本
语境
考虑一个 Django 多表继承,其中一个模型,比如Restaurant(address, serves_pizza)
,继承自父模型,比如Place(name)
。两个模型的字段都在括号中表示。目标是将某个Restaurant
字段,例如address
,转移到父类Place
。一项挑战是通过自定义迁移操作传输数据来保存数据。我觉得很简单的一个想法是
address_place
首先在 中创建一个中间字段Place
,- 然后,手动将数据从
Restaurant.address
(Restaurant.address_place
通过migrations.RunPython
)移动 - 最后删除
address
字段并重命名address_place
为address
着眼于 2.,下面是 by 调用的自定义代码的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
and address_place
。事实上,如果我们检查由Restaurant
返回的模型apps.get_model
,我们可以看到它根本不是从父模型继承的Place
,而只是从基models.Model
...
因此
- 什么可以解释这一点,即
apps.get_model
不保留继承? - 以及如何处理?或者可以使用什么其他方法来解决问题并将字段
address
传递给父类?
编辑——如何重现行为
我认为这种意外行为来自较旧的迁移。一个有点令人沮丧但可行的解决方案是按照@boyenec的建议清理迁移历史。
首先,我尝试在一个最小示例上重现该错误。但是一切正常:没有FieldError
提出。通过检查Restaurant
from apps.get_model("myapp", "Restaurant")
,它按预期继承了 from Place
。在这个最小的例子中,我直接从两个看起来像这样的模型开始:
class Place(models.Model):
name = ...
class Restaurant(Place):
address = ...
serves_pizza = ...
然而,这并不能真正代表我的迁移历史。原本只有Restaurant(name, address, serves_pizza)
. 我创建了它的父类后验,迁移类似于这个想法。在这种情况下,我得到的错误是可重现的。