获取有关创建新Wagtail页面的父页面

时间:2017-06-02 13:53:39

标签: python django wagtail

我需要在创建新页面时从父页面给出一个值来更改一些字段默认值。编辑现有页面时,这不是问题,但在创建新页面时,我需要为字段设置默认值。我试过覆盖管理表单,在init上为WagtailAdminPageForm,parent_page参数为空。如果我尝试在init方法表单页面子类上执行它,则没有包含父信息的arg或kwargs。

有没有办法获得新页面将成为父页面的页面?

这是我在Page构造函数

上尝试的
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

2 个答案:

答案 0 :(得分:2)

在澄清问题之后,这是第二个可能更合适的答案。请注意,此需要Wagtail 1.11.x ,目前尚未发布。

解决方案的示例代码

首先为您的自定义页面表单创建一个新类,通常位于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

第二在页面模型定义上,告诉该模型使用您已定义的表单类

from wagtail.wagtailcore.models import Page

class MyCustomPage(Page):
    base_form_class = MyCustomPageForm

解决方案

的说明
  • Wagtail提供了覆盖在Wagtail Admin中构建表单以进行创建和编辑时调用的表单类(注意:不是模型类)的功能。
  • 文档:Customising generated forms
  • 我们的自定义表单类将继承WagtailAdminPageForm类。
  • 在这个新的表单类中,我们想要定义自己的__init__函数,在创建表单时调用它。
  • 请注意default definition of __init__ on WagtailAdminPageForm
  • 的Github代码
  • 要注入自定义值,我们会在调用该类之前覆盖initial中的kwargs数据。超级__init__
  • 我们只想在创建新页面时执行此操作,因此请检查该实例是否为id
  • 我们可以访问parent_page实例及其中的任何字段
  • 添加我们的自定义初始数据后,我们使用更改过的kwargs调用超级__init__
  • 注意:需要Wagtail 1.11.x的原因是之前的版本直到那时才调用类模型时才添加parent_page,直到pull request 3508

答案 1 :(得分:0)

我建议使用Wooktail Hooks:

http://docs.wagtail.io/en/v1.10.1/reference/hooks.html

这是一个有效的基本示例(在Wagtaildemo应用程序中),在本例中,我只是获取父页面的标题。如果您从父级页面特定模型中获取其他内容,它应该可以正常工作。请注意,这会在创建之后更新记录,而不是创建本身的记录。

# 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并拥有multiple Sites in Wagtail。我不确定你的例子是一个粗略的例子还是你面临的确切问题。