1👍
Proposed Solution
- The Wagtail documentation regarding Customising generated forms explains the method to override the form that gets generated when editing/creating a new page.
- The
WagtailAdminPageForm
extends the DjangoModelForm
and you can extend this further to add customclean
/__init__
/save
etc methods to add essentially any logic you want to both how the form renders and what errors get provided to the user before the save gets applied. - Django ModelForm documentation.
- By default you do not have acesss to the
request
object on form creation, but you do get it on thesave
method so it would be possible to easily do some user basic logic there. - If you need further customisation, you can dig into Wagtail edit handers (search through the source code) and you can create your own edit handler that can pass in the request to your custom
BlogPageForm
. - Note: If the eventual goal is to add a full on ‘process’ based page editing workflow, you may want to look at Wagtails’
ModelAdmin
and essentially just build the blog workflow completely in isolation of the normal page structure and then restructure permissions so that blog editors cannot access the normal page tree but can only access your custom workflow.
Example Code
- This is just a basic example of a custom form for a
BlogPage
model. __init__
can be extended to add custom logic to how the form gets generated (e.g. make some fields read only or even ‘hide’ some fields).save
can be extended to add server side validation to the read only fields and also provide user facing error messaging.- It is possible to add logic for a ‘new’ page creation along with logic for editing an existing page by checking if the self.instance.pk (primary key) exists.
# other imports
from wagtail.admin.forms import WagtailAdminPageForm
class BlogPageForm(WagtailAdminPageForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if not instance.pk:
# this is a NEW blog entry form - only allow title to be enabled, disable other fields
self.fields['description'].widget.attrs['readonly'] = True
if instance.pk:
# assume title has been entered and saved at this point (required for a new post)
# disable the title field
self.fields['title'].widget.attrs['readonly'] = True
def clean(self):
cleaned_data = super().clean()
instance = getattr(self, 'instance', None)
title = cleaned_data['title']
description = cleaned_data['description']
if not instance.pk:
# this is a NEW blog entry, check that only the title has been entered
if not title:
self.add_error('title', 'title must be edited before all other fields')
return cleaned_data
if description:
self.add_error('description', 'description cannot be entered until title has been completed')
if instance.pk:
# an existing blog entry, do not allow title to be changed
print('title', instance.title, title)
if instance.title != title:
self.add_error('title', 'title cannot be edited after the initial save')
class BlogPage(Page):
# ...fields
base_form_class = BlogPageForm
1👍
Can be done easy with additional custom.css file
-
With
insert_global_admin_css
Wagtail hook, add path to your custom.css file. Here is link for documentation: https://docs.wagtail.io/en/latest/reference/hooks.html#insert-global-admin-css -
Then add classname(eg. "myReadonlyInput") to FieldPanel in Page model. This will add new class to li element with input field.
FieldPanel("field_name", classname="myReadonlyInput"),
-
In custom.css file add
pointer-events:none;
to input field that belongs to new class for li element:li.myReadonlyInput div.input input { background-color: rgb(239 239 239); color: rgb(99 99 99); pointer-events:none; cursor:text; }
That way only with adding classname to any field model, input field will be grayed out and not reachable.
- [Django]-Django-uploadify-s3 and HTTP 403 Error
- [Django]-Django Rest Framework add new field in serializer data using existing boolean field
- [Django]-How to download file using django-storage sftp?
- [Django]-Pip install openssl/aes.h error and libxml/xmlversion.h error (osx)
- [Django]-Category() got an unexpected keyword argument 'category_name_slug'
Source:stackexchange.com