I have been looking for a way to find out who the current logged-in user is in Django Wagtail so that I could create a widget to render a base setting field to be editable/non-editable. I was able to get some basic logic working but couldn't figure out how to find who the current logged-in user is. Can someone help me find out what's the best and most secure way to go about this?
@register_setting
class AdminSetting(BaseSetting):
...
permitted_retries = models.IntegerField(null=False, default=10)
panels =[
FieldPanel('permitted_retries', widget=PermittedRetriesWidget())
]
base_form_class = AdminSettingForm
class AdminSettingForm(WagtailAdminPageForm):
def __init__(self, user=None, *args, **kwargs):
self.user = user
super(AdminSettingForm, self).__init__(*args, **kwargs)
self.fields['permitted_retries'].widget.user = 'me' # This goes to widget
def clean(self):
cleaned_data = super().clean()
return cleaned_data
def save(self, commit=True):
page = super().save(commit=False)
if commit:
page.save()
return page
class PermittedRetriesWidget(forms.Widget):
...
def render(self, name, value, attrs=None, renderer=None):
if self.user.is_superuser:
return format_html(f'<input type="hidden" name="{name}" value="{value}" id="id_{name}">')
else:
output = f'<div style="padding: 1.2em;">{value}</div>'
input = f'<input type="hidden" name="{name}" value="{value}" id="id_{name}">'
return format_html(output + input)
I have found another way to do this! This is probably better than ThreadLocal as I have been hearing so much bad things about it. I hope this will help someone out in the future.
class RequestBoundFieldPanel(FieldPanel):
def on_request_bound(self):
if self.widget:
setattr(self.widget, 'request', self.request)
from .panels import RequestBoundFieldPanel(FieldPanel):
@register_setting
class AdminSetting(BaseSetting):
...
permitted_retries = models.IntegerField(null=False, default=10)
panels =[
RequestBoundFieldPanel('permitted_retries', widget=PermittedRetriesWidget())
]
base_form_class = AdminSettingForm
class AdminSettingForm(WagtailAdminPageForm):
def __init__(self, user=None, *args, **kwargs):
super().__init__(*args, **kwargs)
is_superuser = self.fields['permitted_retries'].widget.request.user.is_superuser or False
def clean(self):
cleaned_data = super().clean()
return cleaned_data
def save(self, commit=True):
page = super().save(commit=False)
if commit:
page.save()
return page
class PermittedRetriesWidget(forms.Widget):
...
def __init__(self, attrs=None, *args, **kwargs):
self.request = kwargs.pop('request', None)
super().__init__(*args, **kwargs)
def render(self, name, value, attrs=None, renderer=None):
is_superuser = self.request.user.is_superuser or False
if is_superuser:
# Shows the input as it is
return format_html(f'<input type="number" name="{name}" value="{value}" id="id_{name}">')
else:
# Hide the input and show the value as uneditable
output = f'<div style="padding: 1.2em;">{value}</div>'
input = f'<input type="hidden" name="{name}" value="{value}" id="id_{name}">'
return format_html(output + input)