Reputation: 75
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.
Upvotes: 0
Views: 1120
Reputation: 9463
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'),
]
Upvotes: 1
Reputation: 1
In addition to the answer above (can't add comment to it sorry).
Instead of render_as_field
sometimes you should use render_as_object
. It depends.
Upvotes: 0
Reputation: 8995
... 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.
Upvotes: 0
Reputation: 1
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
)
Upvotes: 0
Reputation: 8023
You can sub-class FieldPanel
and override the render_as_field
and/or render_as_object
methods. Within those methods you will have access to the request, which is bound to the model in bind_to_instance
(see https://github.com/wagtail/wagtail/blob/master/wagtail/admin/edit_handlers.py#L137).
Here's an example:
from wagtail.admin.edit_handlers import FieldPanel
class CustomFieldPanel(FieldPanel):
def render_as_field(self):
if not self.request.user.is_superuser:
return ''
return super().render_as_field()
Upvotes: 1