Elements of the "related objects list" are passed to the
`prep_related_object_data` function before any validation takes place,
with the potential of failing with a hard error. Similar to the "related
objects not list" case explicitly validate the elements general type,
and raise a normal validation error if it isn't a dictionary.
The word "dictionary" is used here, since it is python terminology, and
is close enough to yaml's "mapping". While json calls them "objects",
their key-value syntax should make it obvious what "dictionary" means
here.
The related object fields are not covered by the form, so don't pass
any validation before trying to iterate over them and accessing their
elements. Instead of allowing a hard technical error to be raised,
explicitly check that it is indeed a list, and raise a normal validation
error if not.
The error message is chosen to be similar in format and wording to the
other existing validation errors. The used word "list" is quite
universal, and conveys the wanted meaning in the context of python,
json and yaml.
Integrate `ContactsColumnMixin` into various IPAM and VPN tables to
improve contact management. Updates table fields to include `contacts`.
Fixes#20700
Mark `can_view`, `can_add`, `can_change`, and `can_delete` columns in
the Permissions list as `orderable=False`. Sorting by these computed
flags persisted an invalid sort key which triggers a `FieldError` when
loading `/users/permissions/`.
Fixes#20655
Allow passing a FilterSet to BulkRenameView for consistent behavior with
BulkEditView and BulkDeleteView. Enables the
"Select all N matching query" functionality to expand across the full
queryset. Updates logic to handle PK lists appropriately when editing
all matched objects.
Fixes#20389
The get_view_name() utility function crashed with AttributeError when
called on viewsets that override get_queryset() without setting a
class-level queryset attribute (e.g., ObjectChangeViewSet).
This pattern became necessary in #20089 to force re-evaluation of
valid_models() on each request, ensuring ObjectChange querysets reflect
current ContentType state.
Added None check to fall back to DRF's default view naming when no
class-level queryset exists.
Introduce a view to allow users to dismiss all unread notifications with
a single action. Update the notifications' template to include a
"Dismiss all" button for enhanced usability. This addition streamlines
notification management and improves the user experience.
Fixes#20301
When script form validation fails, display error messages for fields not
in fieldsets. Fields in fieldsets show inline errors only; hidden fields
show toast notifications to provide feedback instead of failing silently.
* Closes#16681: Introduce render_config permission for configuration rendering
Add a new custom permission action `render_config` for rendering device and
virtual machine configurations via the REST API. This allows users to render
configurations without requiring the `add` permission.
Changes:
- Add permission check to RenderConfigMixin.render_config() for devices and VMs
- Update API tests to use render_config permission instead of add
- Add tests verifying permission enforcement (403 without render_config)
- Document new permission requirement in configuration-rendering.md
Note: Currently requires both render_config AND add permissions due to the
automatic POST='add' filter in BaseViewSet.initial(). Removing the add
requirement will be addressed in a follow-up commit.
* Correct permission denied message and enable translation
* Remove add permission requirement for render_config endpoint
Remove the add permission requirement from the render-config API endpoint
while maintaining token write_enabled enforcement as specified in #16681.
Changes:
- Add TokenWritePermission class to check token write ability without requiring
specific model permissions
- Override get_permissions() in RenderConfigMixin to use TokenWritePermission
instead of TokenPermissions for render_config action
- Replace queryset restriction: use render_config instead of add
- Remove add permissions from tests - render_config permission now sufficient
- Update tests to expect 404 when permission denied (NetBox standard pattern)
Per #16681: 'requirement for write permission makes sense for API calls
(because we're accepting and processing arbitrary user data), the specific
permission for creating devices does not'
* Add render_config permission to ConfigTemplate render endpoint
Extend render_config permission requirement to the ConfigTemplate render
endpoint per issue comments.
Changes:
- Add TokenWritePermission check via get_permissions() override in
ConfigTemplateViewSet
- Restrict queryset to render_config permission in render() method
- Add explicit render_config permission check
- Add tests for ConfigTemplate.render() with and without permission
- Update documentation to include ConfigTemplate endpoint
* Address PR feedback on render_config permissions
Remove redundant permission checks, add view permission enforcement via
chained restrict() calls, and rename ConfigTemplate permission action
from render_config to render for consistency.
* Address second round of PR feedback on render_config permissions
- Remove ConfigTemplate view permission check from render_config endpoint
- Add sanity check to TokenWritePermission for non-token auth
- Use named URL patterns instead of string concatenation in tests
- Remove extras.view_configtemplate from test permissions
- Add token write_enabled enforcement tests for all render endpoints
* Misc cleanup
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Switch icons in the top-right User dropdown to Tabler’s
`dropdown-item-icon` to standardize spacing between the icon and label.
Improves readability and ensures alignment with the overall UI styling.
Fixes#20608
* Fixes#20551: Support quick-add form prefix in automatic slug generation
The slug generation logic in `reslug.ts` looks for form fields using hard-coded ID selectors like `#id_slug` and `#id_name`. In quick-add modals, Django applies a `quickadd` prefix to form fields (introduced in #20542), resulting in IDs like `#id_quickadd-slug` and `#id_quickadd-name`. The logic couldn't find these prefixed fields, so automatic slug generation failed silently in quick-add modals. This fix updates the field selectors to try both unprefixed and prefixed patterns using the nullish coalescing operator (`??`), checking for the standard field ID first and falling back to the quickadd-prefixed ID if the standard one isn't found.
* Address PR feedback
The slug generation logic required updates to support form prefixes like `quickadd`. Python-side changes
ensure `SlugField.get_bound_field()` updates the `slug-source` attribute to include the form prefix when
present, so JavaScript receives the correct prefixed field ID. `SlugWidget.__init__()` now adds a
`slug-field` class to enable selector-based field discovery. On the frontend, `reslug.ts` now uses class
selectors (`button.reslug` and `input.slug-field`) instead of ID-based lookups, eliminating the need for
fallback logic. The template was updated to use `class="reslug"` instead of `id="reslug"` on the button to
avoid ID duplication issues.