关于django:如何正确重命名wagtail页面模型

How to properly rename a wagtail page model

我有个模特wagtail APP和A,PageTypeNewPageTypePageTypeNewPageType需要替换。

我想我可以删除从我的PageType运行迁移models.py然后删除它,然后重命名NewPageTypePageType跑一次迁移。

然而,我运行到错误,当我这样做:

1
2
3
4
5
6
7
8
9
10
11
12
[2019-01-22 23:20:26,344] [ERROR] Internal Server Error: /cms/
Traceback (most recent call last):
  File"/.../python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File"/.../python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  [...snip...]
  File"/.../python3.6/site-packages/django/db/models/query.py", line 1121, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File"/.../python3.6/site-packages/wagtail/core/query.py", line 397, in specific_iterator
    yield pages_by_type[content_type][pk]
KeyError: 278

它似乎没有得到的东西,和自动的Django的内置的偏移处理。我不能告诉你在这一步我很乐意得到一些帮助。谢谢!


这是因为wagtail页使用多表继承,并且部分删除的PageType页仍然存在。

让我们来看一下新安装的Wagtail(即wagtail start mysite),它附带了home.HomePage模型,默认情况下创建了一个HomePage。我们可以查看数据库并确认数据库中确实有一个条目:

1
2
3
sqlite> SELECT * FROM home_homepage;
page_ptr_id
3

但它相当空虚。没有标题,没有路径,只有一个page_ptr_id。这是因为HomePage继承自Page模型,这不是抽象的。因此,该页面模型也有一个数据库表(这就是多表继承如何与Django一起工作)。让我们看一下相应的表(自愿地将一些列改为逗号):

1
2
3
4
sqlite> SELECT id, path, title, slug, url_path, content_type_id FROM wagtailcore_page;
id|path    |title|slug|url_path|content_type_id
1 |0001    |Root |root|/       |1
3 |00010001|Home |home|/home/  |2

就在这儿!

同样,在您的例子中,有wagtailcore_pagemyapp_pagetypemyapp_newpagetype表。通过删除PageType模型,django创建了一个迁移,然后删除myapp_pagetype但将条目保留在wagtailcore_page表中。因此,现在,当您加载管理界面时,wagtail尝试加载页面3,但失败。

因此,在删除页面模型之前,需要先删除所有页面。您可以通过向迁移中添加runpython步骤来实现这一点。

尽管Django很难对第二个模型进行重命名,但您仍然需要对其进行重命名,如果幸运的话,在您的models.py文件中对其进行重命名并运行makemigrations可能足以让Django检测到它应该重命名该模型。如果没有,或者如果您有需要重命名为的关系,那么它可能会更复杂,请参见1和2。