0

精简版

我正在尝试运行RunPython涉及继承模型的自定义迁移(通过),例如Restaurant。但是FieldError,在 处引发异常Restaurant.objects.all(),指定无法解析继承的字段。实际上,oddly 返回的模型apps.get_model("myapp", "Restaurant")不是从父类继承的。

更长的版本

语境

考虑一个 Django 多表继承,其中一个模型,比如Restaurant(address, serves_pizza),继承自父模型,比如Place(name)。两个模型的字段都在括号中表示。目标是将某个Restaurant字段,例如address,转移到父类Place。一项挑战是通过自定义迁移操作传输数据来保存数据。我觉得很简单的一个想法是

  1. address_place首先在 中创建一个中间字段Place
  2. 然后,手动将数据从Restaurant.addressRestaurant.address_place通过migrations.RunPython)移动
  3. 最后删除address字段并重命名address_placeaddress

着眼于 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,即nameand address_place。事实上,如果我们检查由Restaurant返回的模型apps.get_model,我们可以看到它根本不是从父模型继承的Place,而只是从基models.Model...

因此

  • 什么可以解释这一点,即apps.get_model不保留继承?
  • 以及如何处理?或者可以使用什么其他方法来解决问题并将字段address传递给父类?

编辑——如何重现行为

我认为这种意外行为来自较旧的迁移。一个有点令人沮丧但可行的解决方案是按照@boyenec的建议清理迁移历史。

首先,我尝试在一个最小示例上重现该错误。但是一切正常:没有FieldError提出。通过检查Restaurantfrom apps.get_model("myapp", "Restaurant"),它按预期继承了 from Place。在这个最小的例子中,我直接从两个看起来像这样的模型开始:

class Place(models.Model):
    name = ...

class Restaurant(Place):
    address = ...
    serves_pizza = ...

然而,这并不能真正代表我的迁移历史。原本只有Restaurant(name, address, serves_pizza). 我创建了它的父类后验,迁移类似于这个想法。在这种情况下,我得到的错误是可重现的。

4

0 回答 0