获取有关创建新的 Wagtail 页面的父页面
Get parent page on creating new Wagtail Page
创建新页面时,我需要根据父页面的值更改某些字段的默认值。在编辑现有页面时,这不是问题,但在创建新页面时,我需要为字段设置默认值。我已经尝试覆盖管理表单,在初始化 WagtailAdminPageForm 时,parent_page 参数为空。如果我尝试在 Page 子类的 init 方法上执行此操作,则没有包含父信息的 arg 或 kwargs。
有没有办法获取新页面将作为父页面的页面?
这是我在页面构造函数上尝试的
class CMSPage(Page):
.
.
.
def __init__(self, *args, **kwargs):
super(BaseContentMixin, self).__init__(*args, **kwargs)
if hasattr(self.get_parent().specific, 'published_site') and self.get_parent().specific.published_site == 'extranet':
self.published_site = 'extranet'
这适用于编辑页面,对于新页面,我发现 NoneType 对象没有特定属性。
Django版本是1.10,Python版本是3.6,Wagtail版本是1.9
我建议使用 Wagtail Hooks:
http://docs.wagtail.io/en/v1.10.1/reference/hooks.html
这是一个有效的基本示例(在 Wagtaildemo 应用程序中),在这个示例中,我只是获取 parent 页面的标题。如果您从 parent 的页面特定模型中获得其他内容,它应该可以正常工作。请注意,这会在记录创建之后更新记录,而不是作为创建本身的一部分。
# my_app/wagtail_hooks.py
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore import hooks
@hooks.register('after_create_page')
def do_after_page_create(request, page):
# get the parent page from the current page
parent = page.get_parent().specific
# get the value from the parent page
parent_title = parent.title
# get a new instance of the page that was just created
new_page = Page.objects.get(id=page.id).specific
# update the value in the page that was just created & save
new_page.parent_title = parent_title
new_page.save()
我经常使用 Wagtail 挂钩,它们运行良好,您可以通过检查 new_page.content_type == "CMSPage"
来进一步完善它,以确保它只更新特定模型的页面。
最后,研究一下 Wagtail 站点的工作原理可能会有所帮助,这可能是针对示例代码中的问题的更具体的解决方案。您可以添加额外的 settings to your Site Model and have multiple Sites in Wagtail。我不确定您的示例是否只是一个粗略的示例或您面临的确切问题。
把问题弄清楚后,这里有第二个答案可能更合适。请注意,此 需要 Wagtail 1。11.x 目前尚未发布。
解决方案示例代码
首先为您的自定义页面表单创建一个新的class,通常在models.py或您的页面模型所在的任何地方。
from wagtail.wagtailadmin.forms import WagtailAdminPageForm
class MyCustomPageForm(WagtailAdminPageForm):
# Override the __init__ function to update 'initial' form values
def __init__(self, data=None, files=None, parent_page=None, *args, **kwargs):
print('parent_page', parent_page, parent_page.id, parent_page.title)
# update the kwargs BEFORE the init of the super form class
instance = kwargs.get('instance')
if not instance.id:
# only update the initial value when creating a new page
kwargs.update(initial={
# 'field': 'value'
'title': parent_page.id # can be anything from the parent page
})
# Ensure you call the super class __init__
super(MyCustomPageForm, self).__init__(data, files, *args, **kwargs)
self.parent_page = parent_page
第二个 在页面模型定义上,告诉该模型使用您定义的class形式
from wagtail.wagtailcore.models import Page
class MyCustomPage(Page):
base_form_class = MyCustomPageForm
解决方案说明
- Wagtail 提供了覆盖表单 class(注意:不是模型 class)的功能,该表单在构建用于在 Wagtail Admin 中创建和编辑的表单时被调用。
- 文档:Customising generated forms
- 我们的自定义表单 class 将继承
WagtailAdminPageForm
class。
- 在这个新表单 class 中,我们要定义我们自己的
__init__
函数,它会在创建表单时调用。
- 请注意 default definition of
__init__
on WagtailAdminPageForm 的 Github 代码
- 为了注入自定义值,我们将在调用 class' super
__init__
之前覆盖 kwargs
中的 initial
数据
- 我们只想在创建新页面时执行此操作,因此请检查该实例是否没有
id
- 我们可以访问
parent_page
实例及其中的任何字段
- 添加自定义初始数据后,我们用更改后的 kwargs
调用 super __init__
- 注意:之所以要求Wagtail 1.11.x是因为之前的版本在调用class模型时没有添加parent_page,直到pull request 3508
创建新页面时,我需要根据父页面的值更改某些字段的默认值。在编辑现有页面时,这不是问题,但在创建新页面时,我需要为字段设置默认值。我已经尝试覆盖管理表单,在初始化 WagtailAdminPageForm 时,parent_page 参数为空。如果我尝试在 Page 子类的 init 方法上执行此操作,则没有包含父信息的 arg 或 kwargs。
有没有办法获取新页面将作为父页面的页面?
这是我在页面构造函数上尝试的
class CMSPage(Page):
.
.
.
def __init__(self, *args, **kwargs):
super(BaseContentMixin, self).__init__(*args, **kwargs)
if hasattr(self.get_parent().specific, 'published_site') and self.get_parent().specific.published_site == 'extranet':
self.published_site = 'extranet'
这适用于编辑页面,对于新页面,我发现 NoneType 对象没有特定属性。
Django版本是1.10,Python版本是3.6,Wagtail版本是1.9
我建议使用 Wagtail Hooks:
http://docs.wagtail.io/en/v1.10.1/reference/hooks.html
这是一个有效的基本示例(在 Wagtaildemo 应用程序中),在这个示例中,我只是获取 parent 页面的标题。如果您从 parent 的页面特定模型中获得其他内容,它应该可以正常工作。请注意,这会在记录创建之后更新记录,而不是作为创建本身的一部分。
# my_app/wagtail_hooks.py
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore import hooks
@hooks.register('after_create_page')
def do_after_page_create(request, page):
# get the parent page from the current page
parent = page.get_parent().specific
# get the value from the parent page
parent_title = parent.title
# get a new instance of the page that was just created
new_page = Page.objects.get(id=page.id).specific
# update the value in the page that was just created & save
new_page.parent_title = parent_title
new_page.save()
我经常使用 Wagtail 挂钩,它们运行良好,您可以通过检查 new_page.content_type == "CMSPage"
来进一步完善它,以确保它只更新特定模型的页面。
最后,研究一下 Wagtail 站点的工作原理可能会有所帮助,这可能是针对示例代码中的问题的更具体的解决方案。您可以添加额外的 settings to your Site Model and have multiple Sites in Wagtail。我不确定您的示例是否只是一个粗略的示例或您面临的确切问题。
把问题弄清楚后,这里有第二个答案可能更合适。请注意,此 需要 Wagtail 1。11.x 目前尚未发布。
解决方案示例代码
首先为您的自定义页面表单创建一个新的class,通常在models.py或您的页面模型所在的任何地方。
from wagtail.wagtailadmin.forms import WagtailAdminPageForm
class MyCustomPageForm(WagtailAdminPageForm):
# Override the __init__ function to update 'initial' form values
def __init__(self, data=None, files=None, parent_page=None, *args, **kwargs):
print('parent_page', parent_page, parent_page.id, parent_page.title)
# update the kwargs BEFORE the init of the super form class
instance = kwargs.get('instance')
if not instance.id:
# only update the initial value when creating a new page
kwargs.update(initial={
# 'field': 'value'
'title': parent_page.id # can be anything from the parent page
})
# Ensure you call the super class __init__
super(MyCustomPageForm, self).__init__(data, files, *args, **kwargs)
self.parent_page = parent_page
第二个 在页面模型定义上,告诉该模型使用您定义的class形式
from wagtail.wagtailcore.models import Page
class MyCustomPage(Page):
base_form_class = MyCustomPageForm
解决方案说明
- Wagtail 提供了覆盖表单 class(注意:不是模型 class)的功能,该表单在构建用于在 Wagtail Admin 中创建和编辑的表单时被调用。
- 文档:Customising generated forms
- 我们的自定义表单 class 将继承
WagtailAdminPageForm
class。 - 在这个新表单 class 中,我们要定义我们自己的
__init__
函数,它会在创建表单时调用。 - 请注意 default definition of
__init__
on WagtailAdminPageForm 的 Github 代码
- 为了注入自定义值,我们将在调用 class' super
__init__
之前覆盖 - 我们只想在创建新页面时执行此操作,因此请检查该实例是否没有
id
- 我们可以访问
parent_page
实例及其中的任何字段 - 添加自定义初始数据后,我们用更改后的 kwargs 调用 super
- 注意:之所以要求Wagtail 1.11.x是因为之前的版本在调用class模型时没有添加parent_page,直到pull request 3508
kwargs
中的 initial
数据
__init__