- Security: remove object names/PKs from ProtectedError detail; report count only
to avoid exposing objects the caller may lack permission to view
- i18n: wrap new error detail strings with _().format() to match codebase convention
- Redundancy: remove superfluous `results and` guard in bulk_destroy (any() on an
empty list already returns False)
- Comment: explain that SequentialBulkCreatesMixin continues provisionally creating
after a failure so cross-object validators see a realistic state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use a valid first item (create_data[0]) alongside an invalid second item ({})
so the test exercises both the 'ok' result shape and the atomic rollback of an
item that would otherwise have been persisted.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use pre-captured `pk` consistently in perform_bulk_destroy error path
- Add comment clarifying the `if results:` sentinel in bulk_update
- Add per-field atomicity assertion to test_bulk_update_objects_validation_error
- Use ID-keyed dict instead of positional index in test_bulk_delete_objects_protected
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bulk update (PATCH), sequential bulk create (POST), and bulk delete (DELETE) on
list endpoints now collect per-object errors instead of aborting on the first
failure. When any objects fail, the entire operation is rolled back atomically
and a 400/409 response is returned with a structured payload:
{
"detail": "1 of 3 objects failed validation.",
"results": [
{"id": 1, "status": "ok"},
{"id": 2, "status": "error", "errors": {"name": ["..."]}},
{"id": 3, "status": "ok"}
]
}
For bulk creates via SequentialBulkCreatesMixin the correlator is "index"
(zero-based position in the request list) since no IDs exist yet. For bulk
delete the status code remains 409 and the correlator is "id".
Successful operations are unchanged (200/201/204).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace ValueError with graceful permission denial when checking
permissions against proxy models or invalid model references. Evaluate
constraints via the permission model's manager and log warnings for
nonexistent models or debug messages for model mismatches.
Fixes#22632
Add test cases for Console, Power, and Interface Connection list views.
Include query count baselines and shared mixin for read-only connection
views that filter by complete cable paths.
Fixes#22577
#22018 switched the row separator on highlighted interface rows to an
opaque colour so it stays visible against tinted backgrounds, but
hardcoded $gray-300 (--tblr-gray-300), a light-theme grey. Because
tr[data-cable-status] matches every interface row, in dark mode this
paints a harsh bright line on every row. Override the separator colour
in dark mode with the theme-aware --tblr-border-color so it stays
visible on tinted rows without being jarring. Light mode is unchanged.
- Annotate the `info` parameter in SharedObjectMixin.get_queryset() with
the Info type for consistency with BaseObjectType.get_queryset()
- Extend the SavedFilter and TableConfig visibility tests to assert that
the owning user can still retrieve their own private object via both the
REST detail endpoint and GraphQL
Update VirtualMachineType default memory labels and display rendering to use
the configured RAM base unit, matching the existing VirtualMachine and
VirtualDisk behavior.
Render default memory with the existing humanized RAM capacity helper and
keep the model field metadata unit-agnostic.
---------
Co-authored-by: Martin Hauser <mhauser@netboxlabs.com>
GraphQL list queries that request tags were issuing one tag lookup query
per object (N+1). TagsMixin declared the field without a prefetch hint;
django-taggit's M2M is not batched by DjangoOptimizerExtension the way
GenericRelations are. Add prefetch_related=['tags'] on the mixin field,
following the pattern from #22061 for journal entries and image
attachments.
Closes#22551
Only display the saved filter dropdown in table controls when a filter
form is present and includes a filter_id field. This prevents rendering
an empty or non-functional dropdown when saved filters are unavailable.
Render navigation menu buttons with the secondary ghost style when their
color is unset or set to the default choice.
This fixes plugin menu buttons, which default to "default" rather than
None, while preserving explicitly configured button colors.