You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

升级Wagtail1.9到2.0与Django1.10到2.0时遇is_relation属性错误

解决Wagtail 1.9 → 2.0 + Django 1.10.6 → 2.0迁移时的AttributeError问题

这个错误AttributeError: 'NoneType' object has no attribute 'is_relation'本质是Django在处理迁移时,找不到某个操作里引用的旧字段,返回None后尝试调用is_relation属性导致的。结合你跨版本升级的场景,我给你分步解决方案:

一、先修正升级路径(核心问题根源)

你直接跨大版本升级Django和Wagtail风险极高——Wagtail 2.0要求Django 1.11+,而你从Django 1.10跳升到2.0,跳过了关键的中间兼容版本,很容易出现迁移逻辑断裂。正确的升级步骤应该是:

  • 第一步:把Django从1.10.6升级到1.11.x(建议用1.11系列的最新稳定版),运行python manage.py migrate确保项目能正常启动和迁移。
  • 第二步:把Wagtail从1.9升级到1.13.x(这是支持Django 1.11的最后一个Wagtail 1.x版本),再次运行迁移验证。
  • 第三步:最后升级Django到2.0,同时升级Wagtail到2.0,执行迁移。

这种渐进式升级能避开很多跨版本的兼容性坑。

二、定位并修复有问题的迁移文件

如果渐进式升级后还是出现错误,或者你想直接排查当前问题,可以按以下步骤操作:

1. 找出出错的具体迁移

从错误栈可以看到,问题出在django/db/migrations/operations/fields.pystate_forwards方法里。你可以临时添加调试代码来定位具体的迁移:
打开虚拟环境里的这个文件(路径是/home/razia/.virtualenvs/web-dj2/lib/python3.6/site-packages/django/db/migrations/operations/fields.py),在报错的delay = not old_field.is_relation这一行之前添加:

# 临时调试代码
print(f"=== Debug Info ===")
print(f"App: {app_label}")
print(f"Model: {self.model_name}")
print(f"Field being modified: {self.name}")
print(f"Existing fields in state: {list(state.models[app_label, self.model_name].fields.keys())}")

然后重新运行python manage.py migrate,控制台会打印出哪个app、哪个模型的哪个字段操作出了问题。

2. 修复迁移文件

找到对应的迁移文件后(比如core/migrations/00XX_xxxx.py),检查里面的AlterFieldRemoveField操作:

  • 如果是AlterField操作:确认里面的model_namename是否对应存在的字段,旧字段的定义是否正确。如果字段已经被移除,你可能需要调整迁移的顺序,或者修改迁移内容使其匹配当前的模型状态。
  • 如果是RemoveField操作:确认这个字段确实存在于之前的模型版本中,或者如果字段已经被提前移除,你可以删除这个多余的RemoveField操作(但要确保不会影响数据)。

三、关键注意事项

  • 备份优先:在做任何修改前,一定要备份你的数据库和代码仓库,防止意外数据丢失。
  • 不要跳过中间版本:跨版本升级很容易导致迁移逻辑不兼容,尤其是Wagtail和Django的版本绑定比较严格,一定要遵循官方的升级指南逐步升级。

内容的提问来源于stack exchange,提问作者Razia Khan

火山引擎 最新活动