DELETE /api/extras/scripts/<pk>/ now deletes the entire ScriptModule
(matching the UI's delete view), including modules with no Script
children (e.g. sync hasn't run yet). Permission check updated to
delete_scriptmodule. The queryset restriction for destroy is removed
since the module is deleted via script.module, not super().destroy().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
super().validate() calls full_clean() on the model instance, which raises
a unique-constraint error for (file_root, file_path) when file_path is
empty (e.g. data_source-only requests). Move the conflict guards above the
super() call so they produce clear, actionable error messages before
full_clean() has a chance to surface confusing database-level errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Match UI error messages for upload+data_file conflict and no-source case
- Keep API-only guards for upload+data_source and data_source-without-data_file
- Restore test_upload_with_data_source_fails
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add the missing checks to ManagedFileForm.clean():
- upload_file + data_source is rejected (matches API)
- data_source without data_file is rejected with a specific message
- Update the 'nothing provided' error to mention data source + data file
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
data_source alone is not a valid creation payload — a data_file must
also be provided to identify which file within the source to sync.
Add the corresponding validation error and a test to cover the case.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DRF 3.16 Serializer.get_value() uses parse_html_dict() or empty for all
HTML/multipart input. A flat key like data_source=2 produces an empty
dict ({}), which is falsy, so it falls back to empty and the nested
field is silently skipped. data.get('data_source') is therefore always
None in multipart requests, bypassing the conflict check.
Fix: also check self.initial_data for data_source and data_file in all
three guards in validate(), so the raw submitted value is detected even
when DRF's HTML parser drops the deserialized object.
Add test_upload_with_data_source_fails to cover the multipart conflict
path explicitly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Catch IntegrityError from the unique (file_root, file_path) constraint
and re-raise as a ValidationError so the API returns a 400 with a clear
message rather than a 500.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- destroy() now checks extras.delete_script (queryset is Script.objects.all())
- create() delegates to self.perform_create() instead of calling serializer.save() directly
- Add comment explaining why update/partial_update intentionally return 405
- Fix test_upload_script_module: set mock_storage.save.return_value so file_path
receives a real string after the _save_upload return-value fix; add DB existence check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix {module} placeholder resolution in module bay position field (#20467)
The {module} placeholder in ModuleBayTemplate's position field was not
being resolved when a module was installed, leaving the literal string
"{module}" in the position. This adds a resolve_position() method and
calls it in instantiate(), consistent with how resolve_name() and
resolve_label() already work.
Consolidates the shared resolution logic into _resolve_module_placeholder()
to eliminate duplication across resolve_name, resolve_label, and the new
resolve_position.
Fixes: #20467
* Move resolve_position() to ModuleBayTemplate
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Implement comprehensive UI panel layouts for all circuit models using
the new panel system. Add panels for providers, circuits, terminations,
groups, and virtual circuits with proper attribute rendering and
actions.
Add support for IEEE 802.3dj 1.6T fixed interface types and
published 1.6T pluggable form factors.
This adds 1.6TBASE-CR8, 1.6TBASE-KR8, 1.6TBASE-DR8, and
1.6TBASE-DR8-2, plus OSFP1600, OSFP1600-RHS, and QSFP-DD1600
transceiver types.
Change port number regex from `\d{2,5}` to `\d{1,5}` to permit valid
single-digit ports (1-9). This aligns with RFC 3986 and fixes
validation for URLs using ports like :8 or :9.
Fixes#21698
Move cache update logic from signal to model save method and track
original values to properly clear old cache when circuit_id or term_side
changes. Add comprehensive tests for all cache update scenarios.
Fixes#21686