如何在 Django Wagtail 的小部件中找出当前登录的用户
How to find out current logged-in user in widget in Django Wagtail
我一直在寻找一种方法来找出 Django Wagtail 中的当前登录用户是谁,这样我就可以创建一个小部件来将基本设置字段呈现为 editable/non-editable。我能够使一些基本逻辑正常工作,但无法弄清楚如何找到当前登录用户是谁。有人可以帮我找出解决此问题的最佳和最安全的方法吗?
models.py
@register_setting
class AdminSetting(BaseSetting):
...
permitted_retries = models.IntegerField(null=False, default=10)
panels =[
FieldPanel('permitted_retries', widget=PermittedRetriesWidget())
]
base_form_class = AdminSettingForm
admin_setting_forms.py
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
widgets.py
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)
我终于通过使用 ThreadLocals 弄明白了,我认为这是更简单快捷的方法。
middleware.py
from django.utils.deprecation import MiddlewareMixin
import threading
_thread_locals = threading.local()
def get_current_request():
return getattr(_thread_locals, 'request', None)
class ThreadLocals(MiddlewareMixin):
"""
Middleware that gets various objects from the
request object and saves them in thread local storage.
"""
def process_request(self, request):
_thread_locals.request = request
admin_settings_form.py
from app.contrib.middleware import get_current_request
class AdminSettingForm(WagtailAdminPageForm):
def __init__(self, user=None, *args, **kwargs):
super().__init__(*args, **kwargs)
current_user = current_request.user
is_superuser = current_user.is_superuser or False
self.fields['permitted_retries'].widget.is_superuser = is_superuser
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
widgets.py
class PermittedRetriesWidget(forms.Widget):
...
def render(self, name, value, attrs=None, renderer=None):
is_superuser = self.is_superuser
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)
我找到了另一种方法!这可能比 ThreadLocal 好,因为我听到过很多关于它的坏话。我希望这对将来的人有所帮助。
panels.py
class RequestBoundFieldPanel(FieldPanel):
def on_request_bound(self):
if self.widget:
setattr(self.widget, 'request', self.request)
models.py
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
admin_settings_form.py
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
widgets.py
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)
我一直在寻找一种方法来找出 Django Wagtail 中的当前登录用户是谁,这样我就可以创建一个小部件来将基本设置字段呈现为 editable/non-editable。我能够使一些基本逻辑正常工作,但无法弄清楚如何找到当前登录用户是谁。有人可以帮我找出解决此问题的最佳和最安全的方法吗?
models.py
@register_setting
class AdminSetting(BaseSetting):
...
permitted_retries = models.IntegerField(null=False, default=10)
panels =[
FieldPanel('permitted_retries', widget=PermittedRetriesWidget())
]
base_form_class = AdminSettingForm
admin_setting_forms.py
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
widgets.py
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)
我终于通过使用 ThreadLocals 弄明白了,我认为这是更简单快捷的方法。
middleware.py
from django.utils.deprecation import MiddlewareMixin
import threading
_thread_locals = threading.local()
def get_current_request():
return getattr(_thread_locals, 'request', None)
class ThreadLocals(MiddlewareMixin):
"""
Middleware that gets various objects from the
request object and saves them in thread local storage.
"""
def process_request(self, request):
_thread_locals.request = request
admin_settings_form.py
from app.contrib.middleware import get_current_request
class AdminSettingForm(WagtailAdminPageForm):
def __init__(self, user=None, *args, **kwargs):
super().__init__(*args, **kwargs)
current_user = current_request.user
is_superuser = current_user.is_superuser or False
self.fields['permitted_retries'].widget.is_superuser = is_superuser
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
widgets.py
class PermittedRetriesWidget(forms.Widget):
...
def render(self, name, value, attrs=None, renderer=None):
is_superuser = self.is_superuser
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)
我找到了另一种方法!这可能比 ThreadLocal 好,因为我听到过很多关于它的坏话。我希望这对将来的人有所帮助。
panels.py
class RequestBoundFieldPanel(FieldPanel):
def on_request_bound(self):
if self.widget:
setattr(self.widget, 'request', self.request)
models.py
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
admin_settings_form.py
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
widgets.py
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)