From 4c291f0463c5aa2e1ae1fc6181f1eba5c597fe26 Mon Sep 17 00:00:00 2001 From: Jason Novinger Date: Fri, 3 Apr 2026 08:07:42 -0500 Subject: [PATCH] Address additional bot review feedback - clean() collects all validation errors before raising instead of stopping at the first - Fix stale admin docs (still referenced "Custom actions" and "grouped by model") --- docs/administration/permissions.md | 2 +- netbox/users/forms/model_forms.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/administration/permissions.md b/docs/administration/permissions.md index 666f8a90b..0b7b88bcd 100644 --- a/docs/administration/permissions.md +++ b/docs/administration/permissions.md @@ -22,7 +22,7 @@ There are four core actions that can be permitted for each type of object within In addition to these, permissions can also grant custom actions that may be required by a specific model or plugin. For example, the `sync` action for data sources allows a user to synchronize data from a remote source, and the `render_config` action for devices and virtual machines allows rendering configuration templates. -Some models have registered custom actions that appear as checkboxes when creating or editing a permission. These are grouped by model under "Custom actions" in the permission form. Additional custom actions (such as those not yet registered or for backwards compatibility) can be entered manually in the "Additional actions" field. +Some models have registered actions that appear as checkboxes in the "Actions" section when creating or editing a permission. These are shown in a flat list alongside the built-in CRUD actions. Additional actions (such as those not yet registered by a plugin, or for backwards compatibility) can be entered manually in the "Additional actions" field. !!! note Internally, all actions granted by a permission (both built-in and custom) are stored as strings in an array field named `actions`. diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py index 9c0141bfd..79b8ef7c7 100644 --- a/netbox/users/forms/model_forms.py +++ b/netbox/users/forms/model_forms.py @@ -480,17 +480,20 @@ class ObjectPermissionForm(forms.ModelForm): action_model_keys = get_action_model_map(dict(registry['model_actions'])) # Validate each selected action is supported by at least one selected object type + errors = [] final_actions = [] for action_name in registered_actions: supported_models = action_model_keys.get(action_name, set()) if not supported_models & selected_models: - raise forms.ValidationError({ - 'registered_actions': _( - 'Action "{action}" is not supported by any of the selected object types.' - ).format(action=action_name) - }) - if action_name not in final_actions: + errors.append( + _('Action "{action}" is not supported by any of the selected object types.').format( + action=action_name + ) + ) + elif action_name not in final_actions: final_actions.append(action_name) + if errors: + raise forms.ValidationError({'registered_actions': errors}) # Append any of the selected CRUD checkboxes to the actions list for action in RESERVED_ACTIONS: