Get Parent Page On Creating New Wagtail Page
Solution 1:
After clarification of the question, here is a second answer that might be more suitable. Note that this requires Wagtail 1.11.x which as at this time is not yet released.
Example Code for Solution
First Create a new class for your custom page form, usually in models.py or wherever the model for your page is.
from wagtail.wagtailadmin.forms import WagtailAdminPageForm
classMyCustomPageForm(WagtailAdminPageForm):
# Override the __init__ function to update 'initial' form valuesdef__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')
ifnot 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
Second On the page model definition, tell that model to use the form class you have defined
from wagtail.wagtailcore.models import Page
classMyCustomPage(Page):
base_form_class = MyCustomPageForm
Explanation of Solution
- Wagtail provides the ability to override the form class (note: not model class) that gets called when building the form for creation and editing in Wagtail Admin.
- Documentation: Customising generated forms
- Our custom form class will inherit the
WagtailAdminPageForm
class. - Inside this new form class, we want to define our own
__init__
function, this is called when the form is created. - Note the Github code for the default definition of
__init__
on WagtailAdminPageForm - To inject custom values, we will override the
initial
data inkwargs
before the calling of the class' super__init__
- We only want to do this when a new page is being created, so check that the instance has no
id
- We can access the
parent_page
instance and any fields in it - After adding our custom initial data, then we call the super
__init__
with the changed kwargs - Note: The reason for the requirement of Wagtail 1.11.x is that previous versions until that point did not add parent_page when calling the class model until pull request 3508
Solution 2:
I would recommend using the Wagtail Hooks:
http://docs.wagtail.io/en/v1.10.1/reference/hooks.html
Here is a basic example that works (in the Wagtaildemo app), in this example, I am just getting the parent page's title. It should work the same if you are getting something else from the parent's page specific model. Note that this updates the record after it has been created, not as part of the creation itself.
# my_app/wagtail_hooks.pyfrom wagtail.wagtailcore.models import Page
from wagtail.wagtailcore import hooks
@hooks.register('after_create_page')defdo_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()
I have used the Wagtail hooks a lot and they work well, you could further refine this by checking the new_page.content_type == "CMSPage"
to ensure this only updates pages of that specific model.
Finally, it might be good to look into how Wagtail sites works, this might be a more specific solution to your issue in the example code. You can add extra settings to your Site Model and have multiple Sites in Wagtail. I am not sure if your example was just a rough example or the exact issue you are facing.
Post a Comment for "Get Parent Page On Creating New Wagtail Page"