Reputation: 828
We're using Wagtail 4.1 and are seeking a way to make some fields in the admin non-editable (read-only).
Normal Django techniques like setting widget.attrs['readonly'] = True
on the form field don't work in Wagtail for most field types. I think this is because the Wagtail admin replaces all the vanilla <input>
elements with dynamically generated javascript-powered fields that look great, but don't respect a form field's "readonly" attribute or any other changes you might make to the underlying <input>
.
As far as I can tell, Wagtail does not provide any built-in mechanism for making admin fields read-only. Maybe I need to write my own custom javascript to override behavior in the Wagtail form?
Any help would be greatly appreciated.
Upvotes: 0
Views: 572
Reputation: 1296
This feature will be available in Wagtail 5.1. But in the mean time you may need to roll your own.
What we did before we knew this was coming out was to use a custom form and then in the form's init, we do the following for each field that needs to be readonly:
# CSS is in place to check for the readonly attribute and .editor-readonly class
# add readonly attribute for inputs
self.fields['title'].widget.attrs['readonly'] = 'readonly'
And then the css is
form#page-edit-form {
section.editor-readonly {
input:read-only {
background-color: #e9ecef;
outline: none;
pointer-events: none;
}
}
}
With this in place, the fields still get submitted in the form but can't be altered from the browser. If you users are sneakier than ours, you might need checking for changes in the clean methods. (We needed the fields to be submitted with the form since we needed several required fields such as title and slug to be readonly.)
RichText fields require some special handling to submit the expected values. For those, the line in form init method looks like:
# Switch description to hide input but also render the paragraph
self.fields['description'].widget = RichTextReadOnlyWidget(
attrs={'readonly': 'readonly'}
)
And the widget is:
class RichTextReadOnlyWidget(HiddenInput):
"""
Displays the richtext while keeping the input hidden.
Wagtail only made features available in DraftailRichTextArea and did not make any other options
available - which means we cannot use Draftail's built in readOnly property. Like
DraftailRichTextArea, we're inheriting from HiddenInput and, instead of initialize the editor,
we're rendering the text so the user can see the content.
"""
template_name = "core/forms/widgets/HTMLReadOnly.html"
And the template file is:
{% load wagtailcore_tags %}
{% include 'django/forms/widgets/hidden.html' %}
{{ widget.value|richtext }}
Upvotes: 0