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.
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
Introduce Boolean filters `assigned` and `primary` to the MACAddress
filterset, improving filtering capabilities. Update forms, tables, and
GraphQL queries to incorporate the new filters. Add tests to validate
the correct functionality.
Fixes#20399
Commit d22246688 added form prefix support to the `GET` handler to fix
Markdown preview functionality in quick add modals. The form prefix
allows Django to properly namespace field names and IDs when rendering
forms within the quick add modal context.
However, the corresponding change was not made to the `POST` handler. This
created a mismatch where form fields were rendered with the `quickadd-`
prefix during `GET` requests, but the `POST` handler instantiated forms
without the prefix. When users submitted quick add forms, Django looked
for unprefixed field names like `address` and `status` in the `POST` data,
but the actual submitted data used prefixed names like `quickadd-address`
and `quickadd-status`. This caused validation to fail immediately with
"This field is required" errors for all required fields, making every
quick add form unusable.
The fix adds the same prefix detection logic to the `POST` handler that was
added to the `GET` handler, checking for the `_quickadd` parameter in the
query string and applying the `quickadd` prefix when present. This ensures
consistent form field naming between rendering and validation.
A regression test has been added to `MACAddressTestCase` to verify that MAC
addresses can be successfully created via the quick add modal, preventing
this issue from recurring. This test should be promoted to a template
test whenever it becomes possible to determine if a model should support
quick-add functionality.
* Closes#19944: Add multi-scenario CSV import testing support with cleanup
Enhanced BulkImportObjectsViewTestCase to support multiple CSV import scenarios via dictionary format,
where each scenario runs as a separate subtest with automatic cleanup. This enables testing different
import configurations (e.g., with/without optional fields) in a single test run with clear output
showing which scenario is being tested.
Introduces cleanupSubTest() context manager that uses database savepoints to automatically roll back
changes between subtests, providing test isolation similar to separate test methods. This allows
subtests to create/modify objects without affecting subsequent subtests in the same test method.
Added post_import_callback parameter to bulk import tests, allowing child classes to inject custom
assertions that run before database cleanup. This solves the inheritance problem where child classes
need to verify imported data but the parent's cleanup would roll back the data before assertions could
run.
The callback approach is cleaner than conditional cleanup parameters - it makes the execution timing
explicit and maintains test isolation while still allowing extensibility.
* Fixup ModuleTypeTestCase bulk import test to work with callback mechamisn
* Update CableTestCase to use expanded CSV scenario testing
* Remove unneeded permission cleanup
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Consolidate scenario name retrieval into method
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Closes#19977: Denormalize site, location, and rack for device components
* Set blank=True on denormalized ForeignKeys
* Populate denormalized field in test data
* Ignore private fields when constructing test GraphQL requests
* feat(dcim): Add site fields to Cable bulk import form
Introduces `side_a_site` and `side_b_site` fields for the Cable bulk
import form. Limits device choices on both sides to the selected site
for improved input validation and consistency.
* feat(dcim): Enhance test data setup with multiple sites
Refactors tests to create multiple sites and assign devices accordingly.
Updates CSV data to include `side_a_site` and `side_b_site` fields for
scenarios involving multiple sites. This improves test coverage and
alignment with real-world use cases.
* docs(dcim): Update comments explaining indent for CSV import
Improved the inline comments to clarify the rationale behind allowing
devices with duplicate names on different sites during CSV bulk import.
* Fixes#19800: ModuleType import supports associating ModuleTypeProfile
* Fixes up ModuleTypeTestCase to include bulk import testing
Also includes an additional regression assertion.
* Address PR feedback
I ultimately left the extra asserts in for test_bulk_import_objects_with_permissionsince
since the parent test is currently only testing against number of
objects successfully imported. Will file a follow up FR to improve that
test.
* feat(dcim): Add VLAN mode filter to CommonInterface
Introduces a new FilterSet for VLAN mode in CommonInterfaceFilterSet.
This allows filtering interfaces based on their VLAN mode using defined
choices.
* feat(dcim): Add VLAN mode filter to Interface FilterForm
Add a field to InterfaceFilterSet to filter interfaces by 802.1Q VLAN
mode.
* feat(virtualization): Add VLAN mode filter to VMInterface
Add a field to VMInterfaceFilterSet to filter interfaces by 802.1Q VLAN
mode.
* fix(dcim): Correct mode filter parameter type in tests
Updates the `mode` filter parameter to accept a list instead of a single
value in `test_filtersets.py`. Ensures proper count assertion for
accurate test behavior.
* feat(virtualization): Add tests for VLAN mode filtering
Introduces tests to validate filtering by `mode` for VMInterface.
Ensures correct filtering for 802.1Q VLAN mode.
* refactor(virtualization): Reorganize FieldSets in FilterSets
Splits the 'Attributes' FieldSet into two distinct FieldSets for better
clarity: 'Attributes' and 'Addressing'. This improves form organization
and makes it more intuitive for users.
* feat(dcim): Add filter by location slug for Device
Introduces a TreeNodeMultipleChoiceFilter for filtering locations by
slug. Enhances filtering flexibility in the Device model by supporting
both ID and slug lookups.
Fixes#19056
* feat(dcim): Add Device filtering by location slug in tests
Extend test cases to include filtering by location slug. Ensures the
FilterSet works correctly with slug-based queries for locations.
Fixes#19056
* fix(forms): Call super().clean() in clean methods
Adds a call to super().clean() in the clean methods of object creation
forms. This ensures base class validation logic is executed properly
before custom logic is applied.
Fixes#19041
* test(forms): Add tests for front port form validation
Introduces unit tests for validating FrontPortCreateForm behavior.
Tests include scenarios for matching and mismatched name-label pairs
to ensure proper form validation logic.
Fixes#19041
* Omit errant print statement
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Move Module & ModuleType models to a separate file
* Add ModuleTypeProfile & related fields
* Initial work on JSON schema validation
* Add attributes property on ModuleType
* Introduce MultipleOfValidator
* Introduce JSONSchemaProperty
* Enable dynamic form field rendering
* Misc cleanup
* Fix migration conflict
* Ensure deterministic ordering of attriubte fields
* Support choices & default values
* Include module type attributes on module view
* Enable modifying individual attributes via REST API
* Enable filtering by attribute values
* Add documentation & tests
* Schema should be optional
* Include attributes column for profiles
* Profile is nullable
* Include some initial profiles to be installed via migration
* Fix migrations conflict
* Fix filterset test
* Misc cleanup
* Fixes#19023: get_field_value() should respect null values in bound forms (#19024)
* Skip filters which do not specify a JSON-serializable value
* Fix handling of array item types
* Fix initial data in schema field during bulk edit
* Implement sanity checking for JSON schema definitions
* Fall back to filtering by string value
Made DeviceRoles hierarchical, had to also change the filtersets for Device, ConfigContext and VirtualMachine to use the TreeNodeMultipleChoiceFilter.
Note: The model was changed to use NestedGroupModel, a side-effect of this is it also adds comments field, but I thought that was better then doing a one-off just for DeviceRole and having to define the fields, validators, etc.. - keeps everything DRY / consistent.
* 18981 Make Device Roles Hierarchical
* 18981 forms, serializer
* 18981 fix tests
* 18981 fix tests
* 18981 fix tests
* 18981 fix tests
* 18981 fix tests
* 18981 fix migration merge
* 18981 fix tests
* 18981 fix filtersets
* 18981 fix tests
* 18981 comments
* 18981 review changes
- [x] 1. Add the field to the model class
- [x] 2. Generate and run database migrations
- [NA] 3. Add validation logic to clean()
- [NA] 4. Update relevant querysets
- [x] 5. Update API serializer
- [x] 6. Add fields to forms
- [x] dcim.forms.model_forms.LocationForm, create/edit (e.g. model_forms.py)
- [x] dcim.forms.buld_edit.LocationBulkEditForm, bulk edit
- [x] dcim.dorms.bulk_import.LocationImportForm, CSV import
- [x] filter (UI and API)
- [NA] UI
- Note: could not find any comments related things in filtersets
- [x] API
- [x] 7. Extend object filter set
- [x] 8. Add column to object table
- [x] 9. Update the SearchIndex
- [x] 10. Update the UI templates
- [x] 11. Create/extend test cases
- [NA] models
- [x] views
- [NA] forms
- [x] filtersets
- [x] api
- [NA] 12. Update the model's documentation
* Fixes: #15924 - Prevent API payload from allowing tagged_vlans while interface mode is set to taged-all
* Prevent cleanup of tagged_vlans when no tagged_vlans set on interface
* Fix test errors
* Remove accidental debug statements
* Update validation to model clean method instead of serializer
* Remove clearing of tagged vlans from `save()`
* Make changes to validation to account for M2M not being available under model in addition to not being able to check incoming vlans under same model.
* Optimize untagged vlan check
* Re-ordering statements in validators
* Forgot to call super().clean()
* Adjust logic for form and serializer. Add tests
* Fix test failure
* Fix ruff errors
* Fix test by removing now invalid test
* Update serializer, form and tests
* Optimize API test for vlan fields
* Optimize API serializer logic
---------
Co-authored-by: Daniel Sheppard <dans@dansheps.com>
Adds:
- dcim.choices.PowerOutletStatusChoices
- dcim.models.device_components.PowerOutlet.status field with `choices`
set to PowerOutletStatusChoices
- adds migration for PowerOutlet.status field
- updates breaking view tests