angrybeanie_wagtail/env/lib/python3.12/site-packages/wagtail/contrib/settings/registry.py

138 lines
4.2 KiB
Python
Raw Normal View History

2025-07-25 21:32:16 +10:00
from django.apps import apps
from django.contrib.auth.models import Permission
from django.urls import reverse
from django.utils.text import capfirst
from wagtail import hooks
from wagtail.admin.admin_url_finder import (
ModelAdminURLFinder,
register_admin_url_finder,
)
from wagtail.admin.menu import MenuItem
from wagtail.permission_policies import ModelPermissionPolicy
from .permissions import user_can_edit_setting_type
class SettingMenuItem(MenuItem):
def __init__(self, model, icon="cog", classname="", **kwargs):
self.model = model
super().__init__(
label=capfirst(model._meta.verbose_name),
url=reverse(
"wagtailsettings:edit",
args=[model._meta.app_label, model._meta.model_name],
),
classname=classname,
icon_name=icon,
**kwargs,
)
def is_shown(self, request):
return user_can_edit_setting_type(request.user, self.model)
class SiteSettingAdminURLFinder(ModelAdminURLFinder):
def construct_edit_url(self, instance):
return reverse(
"wagtailsettings:edit",
args=[
self.model._meta.app_label,
self.model._meta.model_name,
instance.site_id,
],
)
class GenericSettingAdminURLFinder(ModelAdminURLFinder):
def construct_edit_url(self, instance):
return reverse(
"wagtailsettings:edit",
args=[
self.model._meta.app_label,
self.model._meta.model_name,
instance.id,
],
)
class Registry(list):
def __init__(self):
self._model_icons = {}
def register(self, model, icon="cog", **kwargs):
from .models import BaseGenericSetting, BaseSiteSetting
"""
Register a model as a setting, adding it to the wagtail admin menu
"""
if icon:
self._model_icons[model] = icon
# Don't bother registering this if it is already registered
if model in self:
return model
self.append(model)
# Register a new menu item in the settings menu
@hooks.register("register_settings_menu_item")
def menu_hook():
return SettingMenuItem(model, icon=self._model_icons.get(model), **kwargs)
@hooks.register("register_permissions")
def permissions_hook():
return Permission.objects.filter(
content_type__app_label=model._meta.app_label,
codename=f"change_{model._meta.model_name}",
)
# Register an admin URL finder
permission_policy = ModelPermissionPolicy(model)
if issubclass(model, BaseSiteSetting):
finder_class = type(
"_SiteSettingAdminURLFinder",
(SiteSettingAdminURLFinder,),
{"model": model, "permission_policy": permission_policy},
)
elif issubclass(model, BaseGenericSetting):
finder_class = type(
"_GenericSettingAdminURLFinder",
(GenericSettingAdminURLFinder,),
{"model": model, "permission_policy": permission_policy},
)
else:
raise NotImplementedError
register_admin_url_finder(model, finder_class)
return model
def register_decorator(self, model=None, icon="cog", **kwargs):
"""
Register a model as a setting in the Wagtail admin
"""
if model is None:
return lambda model: self.register(model, icon=icon, **kwargs)
return self.register(model, icon=icon, **kwargs)
def get_by_natural_key(self, app_label, model_name):
"""
Get a setting model using its app_label and model_name.
If the app_label.model_name combination is not a valid model, or the
model is not registered as a setting, returns None.
"""
try:
Model = apps.get_model(app_label, model_name)
except LookupError:
return None
else:
if Model not in registry:
return None
return Model
registry = Registry()
register_setting = registry.register_decorator