My app have some models that can be edited with modelAdmin. Is it possible that some fieldpanels are hidden to some types of users?
I can't find in the docs how to modify dynamically the edit_handler depending of the type of user.
My app have some models that can be edited with modelAdmin. Is it possible that some fieldpanels are hidden to some types of users?
I can't find in the docs how to modify dynamically the edit_handler depending of the type of user.
There is an another way which I found recently (also faced with this problem).
If you don't need to hide panel but only make it read-only, you can just create let's say NewFieldPanel
inherited from base FieldPanel
and override bind_to_instance
method (originally found the tip here).
The example of implementation:
class NewFieldPanel(FieldPanel):
def bind_to_instance(self, instance=None, form=None, request=None):
# form.fields['managers'].widget = HiddenInput()
form.fields['managers'].disabled = True
return super().bind_to_instance(
instance=instance, form=form, request=request
)
... now, if it were me, I would probably opt to set up two entirely different panels, even though they would be maintained together and would look the same. Because, "sooner or sooner," one view will diverge from the other, and this can add complexity very quickly. Therefore, appealing though it may be to approach this problem by "selectively hiding things," you might come to wish that you hadn't done it this way. I think it's better to have two redundant panels, with a clean implementation for each, than to have two pieces of code that become littered with if
-statements ... but that is strictly my opinion.
Another approach. Make the required_fields
method return an empty list.
# panels.py
from wagtail.admin.edit_handlers import FieldPanel
class PermissionFieldPanel(FieldPanel):
def __init__(self, *args, permission: str, **kwargs):
super().__init__(*args, **kwargs)
self.permission = permission
def clone_kwargs(self):
kwargs = super().clone_kwargs()
kwargs['permission'] = self.permission
return kwargs
def required_fields(self):
if self.request and self.request.user.has_perm(self.permission):
return super().required_fields()
return []
# models.py
from wagtail.core.models import Page
form panels import PermissionFieldPanel
class ArticlePage(Page):
admin_notes = models.TextField(blank=True)
settings_panels = Page.settings_panels + [
PermissionFieldPanel('admin_notes', permission='myapp__some_permission'),
]
You can sub-class
FieldPanel
and override therender_as_field
and/orrender_as_object
methods. Within those methods you will have access to the request, which is bound to the model inbind_to_instance
(see https://github.com/wagtail/wagtail/blob/master/wagtail/admin/edit_handlers.py#L137).Here's an example: