Reputation: 1412
I need to change some field default value given a value from the parent page when creating a new page. When editing an existing page, this is not a problem, but when creating a new page, I need to set a default value for a field. I have tried overriding the admin form, on init for WagtailAdminPageForm, the parent_page parameter is empty. And if I try to do it on the init method form Page subclass, there is no arg or kwargs with the parent information.
is there a way to get the page for which the new page will be the parent?
This is what I tried on Page constructor
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'
This works editing a page, for new page, I get that NoneType objects has no attribute specific.
Django version is 1.10, Python version is 3.6, Wagtail version is 1.9
Upvotes: 5
Views: 5818
Reputation: 5176
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.
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
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
Second On the page model definition, tell that model to use the form class you have defined
from wagtail.wagtailcore.models import Page
class MyCustomPage(Page):
base_form_class = MyCustomPageForm
WagtailAdminPageForm
class.__init__
function, this is called when the form is created.__init__
on WagtailAdminPageForminitial
data in kwargs
before the calling of the class' super __init__
id
parent_page
instance and any fields in it__init__
with the changed kwargsUpvotes: 4
Reputation: 5176
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.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()
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.
Upvotes: 1