Commit Graph

226 Commits

Author SHA1 Message Date
Martin Hauser
ef52ac4203 chore(ruff): Enable RET rules and add explicit fallbacks
Adopt Ruff `RET` to improve return-flow consistency across the codebase.
Simplify control flow by removing redundant `else` blocks after
`return`, and add explicit `return None` (or equivalent) fallbacks
where appropriate to preserve existing behavior.

Fixes #21411
2026-02-18 16:49:36 -05:00
Martin Hauser
945e7ade0a Fixes #21407: Enable I (isort) and stabilize import ordering (#21458)
- Adopt Ruff `I` (isort) rules for consistent import sorting
- Add two `# isort: split` boundaries to keep required imports pinned
  in `__init__.py` modules
2026-02-18 10:41:51 -06:00
Jeremy Stretch
1190adde2b Closes #21419: Improve query efficiency for MultipleChoiceFilter (#21421)
* Pass distinct=False to all ModelMultipleChoiceFilters associated with a ForeignKey field

* Pass distinct=False to all MultipleChoiceFilters associated with a concrete model
2026-02-13 12:31:36 +01:00
Jeremy Stretch
dc738c7102 Closes #21257: Introduce & adopt MultiValueContentTypeFilter (#21417) 2026-02-13 04:24:36 -06:00
Jeremy Stretch
76fd3e3c61 Fixes #21196: q filter should match on primary IP only for IP address values (#21401) 2026-02-13 04:08:01 -06:00
Jeremy Stretch
6f2ba5c75c Merge branch 'main' into feature 2026-01-06 13:05:07 -05:00
vo42
f371004809 Fixes #20969: Fix FrontPortTemplateFilterSet rear_port_id queryset. (#20987) 2025-12-16 11:23:18 -08:00
Jeremy Stretch
875e3e7979 Additional work for FR #20788 (#20973) 2025-12-15 14:41:07 -06:00
Jeremy Stretch
17d8f78ae3 Closes #20564: Many-to-many pass-through port mappings (#20851) 2025-12-09 09:17:17 -08:00
Jeremy Stretch
97d0a16fd4 Merge branch 'main' into feature 2025-12-09 11:50:37 -05:00
Etienne.BRUNEL
a4ee323cb6 Add tenant filter on device components. 2025-12-09 10:04:41 -05:00
Jason Novinger
7eefb07554 Closes #7604: Add filter modifier dropdowns for advanced lookup operators (#20747)
* Fixes #7604: Add filter modifier dropdowns for advanced lookup operators

Implements dynamic filter modifier UI that allows users to select lookup operators
(exact, contains, starts with, regex, negation, empty/not empty) directly in filter
forms without manual URL parameter editing.

Supports filters for all scalar types and strings, as well as some
related object filters. Explicitly does not support filters on fields
that use APIWidget. That has been broken out in to follow up work.

**Backend:**
- FilterModifierWidget: Wraps form widgets with lookup modifier dropdown
- FilterModifierMixin: Auto-enhances filterset fields with appropriate lookups
- Extended lookup support: Adds negation (n), regex, iregex, empty_true/false lookups
- Field-type-aware: CharField gets text lookups, IntegerField gets comparison operators, etc.

**Frontend:**
- TypeScript handler syncs modifier dropdown with URL parameters
- Dynamically updates form field names (serial → serial__ic) on modifier change
- Flexible-width modifier dropdowns with semantic CSS classes

* Remove extraneous TS comments

* Fix import order

* Fix CircuitFilterForm inheritance

* Enable filter form modifiers on DCIM models

* Enable filter form modifiers on Tenancy models

* Enable filter form modifiers on Wireless models

* Enable filter form modifiers on IPAM models

* Enable filter form modifiers on VPN models

* Enable filter form modifiers on Virtualization models

* Enable filter form modifiers on Circuit models

* Enable filter form modifiers on Users models

* Enable filter form modifiers on Core models

* Enable filter form modifiers on Extras models

* Add ChoiceField support to FilterModifierMixin

Enable filter modifiers for single-choice ChoiceFields in addition to the
existing MultipleChoiceField support. ChoiceFields can now display modifier
dropdowns with "Is", "Is Not", "Is Empty", and "Is Not Empty" options when
the corresponding FilterSet defines those lookups.

The mixin correctly verifies lookup availability against the FilterSet, so
modifiers only appear when multiple lookup options are actually supported.
Currently most FilterSets only define 'exact' for single-choice fields, but
this change enables future FilterSet enhancements to expose additional
lookups for ChoiceFields.

* Address PR feedback: Replace global filterset mappings with registry

* Address PR feedback: Move FilterModifierMixin into base filter form classes

Incorporates FilterModifierMixin into NetBoxModelFilterSetForm and FilterForm,
making filter modifiers automatic for all filter forms throughout the application.

* Fix filter modifier form submission bug with 'action' field collision

Forms with a field named "action" (e.g., ObjectChangeFilterForm) were causing
the form.action property to be shadowed by the field element, resulting in
[object HTMLSelectElement] appearing in the URL path.

Use form.getAttribute('action') instead of form.action to reliably retrieve
the form's action URL without collision from form fields.

Fixes form submission on /core/changelog/ and any other forms with an 'action'
field using filter modifiers.

* Address PR feedback: Move FORM_FIELD_LOOKUPS to module-level constant

Extracts the field type to lookup mappings from FilterModifierMixin class
attribute to a module-level constant for better reusability.

* Address PR feedback: Refactor and consolidate field filtering logic

Consolidated field enhancement logic in FilterModifierMixin by:
- Creating QueryField marker type (CharField subclass) for search fields
- Updating FilterForm and NetBoxModelFilterSetForm to use QueryField for 'q'
- Moving all skip logic into _get_lookup_choices() to return empty list for
  fields that shouldn't be enhanced
- Removing separate _should_skip_field() method
- Removing unused field_name parameter from _get_lookup_choices()
- Replacing hardcoded field name check ('q') with type-based detection

* Address PR feedback: Refactor applied_filters to use FORM_FIELD_LOOKUPS

* Address PR feedback: Rename FilterModifierWidget parameter to widget

* Fix registry pattern to use model identifiers as keys

Changed filterset registration to use model identifiers ('{app_label}.{model_name}')
as registry keys instead of form classes, matching NetBox's pattern for search indexes.

* Address PR feedback: refactor brittle test for APISelect useage

Now checks if widget is actually APISelect, rather than trying to infer
from the class name.

* Refactor register_filterset to be more generic and simple

* Remove unneeded imports left from earlier registry work

* Update app registry for new `filtersets` store

* Remove unused star import, leftover from earlier work

* Enables filter modifiers on APISelect based fields

* Support filter modifiers for ChoiceField

* Include MODIFIER_EMPTY_FALSE/_TRUE in __all__

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* Fix filterset registration for doubly-registered models

* Removed explicit checks against QueryField and [Null]BooleanField

I did add them to FORM_FIELD_LOOKUPS, though, to underscore that they
were considered and are intentially empty for future devs.

* Switch to sentence case for filter pill text

* Fix applied_filters template tag to use field-type-specific lookup labelsresolves

E.g. resolves gt="after" for dates vs "greater than" for numbers

* Verifies that filter pills for exact matches (no lookup
Add test for exact lookup filter pill rendering

* Add guard for FilterModifierWidget with no lookups

* Remove comparison symbols from numeric filter labels

* Match complete tags in widget rendering test assertions

* Check all expected lookups in field enhancement tests

* Move register_filterset to netbox.plugins.registration

* Require registered filterset for filter modifier enhancements

Updates FilterModifierMixin to only enhance form fields when the
associated model has a registered filterset. This provides plugin
safety by ensuring unregistered plugin filtersets fall back to
simple filters without lookup modifiers.

Test changes:
- Create TestModel and TestFilterSet using BaseFilterSet for
automatic lookup generation
- Import dcim.filtersets to ensure Device filterset registration
- Adjust tag field expectations to match actual Device filterset
(has exact/n but not empty lookups)

* Attempt to resolve static conflicts

* Move register_filterset() back to utilities.filtersets

* Add register_filterset() to plugins documentation for filtersets

* Reorder import statements

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2025-12-05 15:13:37 -05:00
Jeremy Stretch
7cc7c7ab81 Closes #20788: Cable profiles and and position mapping (#20802) 2025-11-25 12:18:15 -06:00
Martin Hauser
cee2a5e0ed feat(dcim): Add device, module and rack count filters
Introduces `device_count`, `module_count` and `rack_count` filters to
enable queries based on the existence and count of the associated
device, module or rack instances.
Updates forms, filtersets, and GraphQL schema to support these filters,
along with tests for validation.

Fixes #19523
2025-11-17 08:39:54 -05:00
Jeremy Stretch
068d493cc6 Merge branch 'main' into feature 2025-10-29 13:47:01 -04:00
Jeremy Stretch
be74436884 Closes #20304: Object owners (#20634) 2025-10-24 13:08:01 -07:00
Alexander
52d4498caf Add color to PowerOutletTemplate (#20530) 2025-10-24 11:11:55 -07:00
Jeremy Stretch
3bd0186870 Fixes #20637: Omit inventory item serials from device search filter to improve performance 2025-10-23 10:11:08 -04:00
Martin Hauser
bbb330becf feat(filtersets): Add assigned and primary filters for MACAddress (#20620)
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
2025-10-20 10:01:25 -07:00
Martin Hauser
f23ee0a46f feat(filtersets): Add ContentTypeFilter to enhance filtering
Introduce `ContentTypeFilter` across several filtersets, including
`object_type`, `related_object_type`, `assigned_object_type`, and
`parent_object_type`. This improvement enhances filtering specificity
and aligns with existing usability standards.

Closes #20554
2025-10-15 18:24:42 +02:00
Jeremy Stretch
d433456e2f Merge branch 'main' into feature 2025-09-02 10:50:58 -04:00
Daniel Sheppard
9f605a2db1 Fixes #19645: Correct Interface selection for Cable add when VC master is the selected device (#20041)
* Fixes: #19645 - Correct Interface selection for Cable add when VC master is the selected device

* Clarify label

* Add test
2025-08-15 13:54:18 -05:00
Jeremy Stretch
a7247f8815 Merge branch 'main' into feature 2025-08-12 16:03:45 -04:00
Jeremy Stretch
bb57021197 Closes #18984: Add status field to Rack model (#20080) 2025-08-12 12:35:50 -05:00
Jeremy Stretch
148fac1086 Closes #19740: Enable recursive nesting for platforms 2025-08-07 16:19:24 -04:00
Jeremy Stretch
aa9ee0e5c6 Closes #19977: Denormalize device relationships on component models (#19984)
* 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
2025-08-01 15:40:15 -05:00
Jeremy Stretch
77f0eeb7bf Fixes #19587: Occupied filter should match on interfaces terminating a wireless link (#19631) 2025-06-03 07:34:39 -07:00
Jeremy Stretch
64b5867cb3 Merge branch 'main' into feature 2025-05-01 09:45:38 -04:00
Arthur Hanson
18ac29fdd0 18334 add location, device, site to module filters (#19312)
* 18334 add location, device, site to module filters

* 18334 add location, device, site to module filters

* 18334 add tests

* 18334 fix tests

* 18334 add site-group
2025-04-28 08:46:38 -04:00
Jeremy Stretch
6c7a0cf2b2 Merge branch 'main' into feature 2025-04-22 16:36:17 -04:00
Martin Hauser
1f93471659 Fixes #18978 - Allow filtering of Interfaces in the GUI by 802.1Q Mode (#19183)
* 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.
2025-04-15 13:47:51 -04:00
Martin Hauser
44cb1a9139 Fixes #19056 – Add Device filtering by Location slug (#19180)
* 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
2025-04-15 08:22:59 -04:00
Jeremy Stretch
fc0acb020f Merge main into feature 2025-04-10 17:17:21 -04:00
Jeremy Stretch
8d7889e2c0 Closes #19002: Module type profiles (#19014)
* 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
2025-04-01 12:05:06 -05:00
Arthur Hanson
1508e3a770 Fixes #18245: Make DeviceRole Hierarchical (#19008)
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
2025-03-28 14:32:02 -05:00
Arthur Hanson
7a71c7b8f8 18417 Add outer_height to racks (#18940)
* 18417 add rack outer height

* 18417 add rack outer height

* 18417 fix tests

* 18417 fix validation message

* Update netbox/dcim/filtersets.py

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* Update netbox/dcim/filtersets.py

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* Update netbox/dcim/models/racks.py

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* Update netbox/dcim/models/racks.py

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* Update netbox/dcim/models/racks.py

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* Update netbox/dcim/models/racks.py

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* 16224 review changes

* 16224 review changes

* 16224 update table display

* 18417 use TemplateColumn

* 18417 review changes

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2025-03-26 08:42:13 -04:00
Jason Novinger
06a206ee33 Extract base NestedGroupModelFilterSet with base search behavior
This can easily be extended (as in the case of LocationFilterSet) by
calling super() and ORing a filter to the queryset that is returned.
See: https://docs.djangoproject.com/en/5.1/ref/models/querysets/#or
2025-03-13 15:36:55 -05:00
Jason Novinger
2df68e29c9 Ensures overridden filterset search() methods include fields from OrganizationalModelFilterSet 2025-03-13 11:52:06 -05:00
Jason Novinger
ed98756f3e Adds SiteGroup.comments in the required locations
- [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)
- [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
- [x] 12. Update the model's documentation
2025-03-13 11:52:06 -05:00
Jason Novinger
9a9d6cdedb Adds Region.comments field in the required locations
- [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
- [ ] 6. Add fields to forms
    - [x] dcim.forms.model_forms.RegionForm, create/edit (e.g. model_forms.py)
    - [x] dcim.forms.buld_edit.RegionBulkEditForm, bulk edit
    - [x] dcim.dorms.bulk_import.RegionImportForm, CSV import
    - [NA] filter (UI and 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
2025-03-13 11:52:06 -05:00
Jason Novinger
44efd5e833 Adds Location.comments field in the required locations
- [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
2025-03-13 11:52:06 -05:00
Jason Novinger
d9d7955c19 For #18352, adds PowerOutlet.status field to forms and filtersets 2025-02-26 16:38:11 -06:00
Alexander Haase
bf836c9bc2 Fixes 17357: Use virtual chassis name as fallback for device (#18710) 2025-02-25 07:55:00 -08:00
Daniel Sheppard
c56a39a168 Fixes: #18449 - Clean up some formatting errors 2025-01-21 10:44:46 -06:00
Jeremy Stretch
343a4af591 Closes #18022: Extend linter (ruff) to enforce line length limit (120 chars) (#18067)
* Enable E501 rule
* Configure ruff formatter
* Reformat migration files to fix line length violations
* Fix various E501 errors
* Move table template code to template_code.py & ignore E501 errors
* Reformat raw SQL
2024-11-21 15:58:11 -05:00
Jeremy Stretch
d2168b107f Closes #13086: Virtual circuits (#17933)
* WIP

* Add API tests

* Add remaining tests

* Add model docs

* Show virtual circuit connections on interfaces

* Misc cleanup per PR feedback

* Renumber migration

* Support nested terminations for virtual circuit bulk import
2024-11-19 10:58:39 -05:00
bctiemann
353214098b 4867 multiple mac addresses (#17902)
* Create MACAddress model and migrations to convert existing .mac_address fields to standalone objects

* Add migrations

* All views/filtering working and documentation done; no unit tests yet

* Redo migrations following VLAN Translation

* Remove mac_address filter fields and add table columns for device/vm

* Remove unnecessary "bulk rename"

* Fix filterset tests for Device

* Fix filterset tests for Interface

* Fix tests on single-object forms

* Fix serializer tests

* Fix filterset tests for VMInterface

* Fix filterset tests for Device and VirtualMachine

* Move new field check into lookup_map iteration

* Fix general MACAddress filter tests

* Add GraphQL types/filters/schema

* Fix bulk edit/create tests (bulk editing Interfaces will be unsupported because of inheritance from ComponentBulkEditForm)

* Make mac_address read_only on InterfaceSerializer/VMInterfaceSerializer

* Undo unrelated work

* Cleanup unused IPAddress derived stuff

* API endpoints

* Add serializer objects to interface serializers

* Clean up unnecessary bulk create forms/views/routes

* Add SearchIndex and adjust indexable fields for Interface and VMInterface

* Reorganize MACAddress classes out of association with DeviceComponents

* Move MACAddressSerializer

* Enforce saving only a single is_primary MACAddress per interface/vminterface

* Perform is_primary validation on MACAddress model and just check if one already exists for the interface

* Remove form-level validation

* Fix check for current is_primary setting when reassigning

* Model cleanup

* Documentation notes and cleanup

* Simplify serializer and add ip_addresses

* Add to VMInterfaceSerializer too

* Style cleanup

* Standardize "MAC Address" instead of "MAC"

* Remove unused views

* Add is_primary field for bulk edit

* HTML cleanup and add copy-to-clipboard button

* Remove mac_address from Interface and VMInterface bulk-edit forms

* Add device and VM filtering

* Use combined assigned_object_parent in table to match structure of IPAddressTable

* Add GFK fields to MACAddressSerializer

* Reorganize "Addressing" sections to remove from proximity to "Device Components" and related groupings

* Clean up migrations

* Misc cleanup

* Add filterset test

* Remove mac_address field from interface forms

* Designate primary MAC address via a ForeignKey on the interface models

* Add serializer fields for primary_mac_address

* Update docs

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2024-11-18 15:11:24 -05:00
Arthur Hanson
9fe6685562 17929 Add Scope Mixins to Prefix (#17930)
* 17929 Add Scope Mixins to Prefix

* 17929 Add Scope Mixins to Prefix

* 17929 fixes for tests

* 17929 merge latest scope changes

* 12596 review changes

* 12596 review changes

* 12596 review changes

* 12596 review changes

* 12596 review changes

* 12596 review changes

* 17929 fix migrations
2024-11-15 14:55:46 -05:00
Arthur Hanson
6dc75d8db1 7699 Add Scope to Cluster (#17848)
* 7699 Add Scope to Cluster

* 7699 Serializer

* 7699 filterset

* 7699 bulk_edit

* 7699 bulk_import

* 7699 model_form

* 7699 graphql, tables

* 7699 fixes

* 7699 fixes

* 7699 fixes

* 7699 fixes

* 7699 fix tests

* 7699 fix graphql tests for clusters reference

* 7699 fix dcim tests

* 7699 fix ipam tests

* 7699 fix tests

* 7699 use mixin for model

* 7699 change mixin name

* 7699 scope form

* 7699 scope form

* 7699 scoped form, fitlerset

* 7699 review changes

* 7699 move ScopedFilterset

* 7699 move CachedScopeMixin

* 7699 review changes

* 7699 review changes

* 7699 refactor mixins

* 7699 _sitegroup -> _site_group

* 7699 update docstring

* Misc cleanup

* Update migrations

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2024-11-01 14:18:23 -04:00
Jeremy Stretch
8767fd8186 Closes #13428: Q-in-Q VLANs (#17822)
* Initial work on #13428 (QinQ)

* Misc cleanup; add tests for Q-in-Q fields

* Address PR feedback
2024-10-31 14:17:06 -04:00