Django迁移拒绝承认模型不再继承旧父母

时间:2015-10-19 01:31:52

标签: django django-migrations

我正在尝试删除具体的父模型,并将其中的一些字段直接复制到子项上。在使用South(与其他孩子相同的父模型)之前,我已经多次执行了类似的过程,但是自从升级到Django 1.7后,它就没有玩游戏了。 Django在migrate进程中出现以下错误:

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

在运行makemigrationsmigrate并且发生此错误时,父模型不再作为类的父级出现在代码中,但迁移仍然会抱怨。

类似的问题has been asked here before和接受的解决方案涉及创建新模型,将数据复制到其中,替换现有模型以及复制数据。不幸的是,这种方法在我的情况下不起作用。它是一个已建立的模型,有许多外键指向它,如果原始记录被删除,它将丢失。

我在南方使用的(简化)方法是:

  1. 删除模型作为父项并将新字段添加到子项
  2. 添加与旧的自动*_ptr_id字段
  3. 同名的显式主键字段
  4. 运行schemamigration并将文件编辑为:

    • 删除South尝试删除并重新创建*_ptr字段
    • 添加一些自定义逻辑以删除*_ptr_id字段的ForeignKey-ness并添加PrimaryKey-ness
  5. 使用datamigration从旧父级获取值并将其添加到子级的新字段
  6. 这是我希望能够合理地轻松适应原生Django迁移的方法,并且我(通过一些调整)得到了*_ptr_id字段替换逻辑。但是Django不会让我添加新字段。我尝试过以下方法:

    • 删除父模型并执行自定义*_ptr_id替换,迁移和添加字段作为第二次迁移。
    • 删除父模型并编辑文件以手动弄乱*_ptr_id,但保留Django的删除/添加操作并使用--fake进行迁移。

    在这两种情况下,稍后迁移会添加与旧父字段名称相同的新字段,从而导致上述错误。 Django拒绝承认旧的父模型不再是该类的父类。

    还有其他人遇到过这个问题并能够解决这个问题吗?

    修改

    这似乎是由列出父模型的bases模式操作类的CreateModel参数引起的,并且缺少用于更新列表的匹配操作。 documentation for CreateModel将此参数列为可选参数,但在先前应用的迁移中是否存在手动更改此值的任何副作用?

1 个答案:

答案 0 :(得分:1)

在Django 1.11中遇到同样的问题后,我按照编辑过的建议,在我的迁移文件中找到了初始的“CreateModel”调用。在评论bases=('{appname}.{modelname}',),行并明确将我的模型主键设置为'id'后,重新运行makemigrationsmigrate为我解决了问题。

我不确定主键更改是否与解决方案相关,我只是在计算变量。

对于模型名称(和数据)投入较少的人的另一种选择:删除父项时重命名。请注意,虽然这对我有用,但在另一次迁移中切换回原始模型名称时会出现同样的“一次孩子,总是孩子”错误,因此您仍需要在迁移中编辑“bases =”行。

感谢oogles和社区!