Commit Graph

688 Commits

Author SHA1 Message Date
Martin Hauser
53345f194a refactor(graphql): Replace FilterLookup[str] with StrFilterLookup
Replace usages of FilterLookup[str] with StrFilterLookup in GraphQL
filter definitions to align with strawberry-graphql-django v0.75.1.
This silences upstream warnings and helps avoid DuplicatedTypeName
errors.

Fixes #21450
2026-03-03 11:17:13 -05:00
Martin Hauser
3beef34355 chore(ruff): Sort __all__ definitions across modules
Apply consistent alphabetical ordering to `__all__` lists in the
circuits module. Enhances readability and alignment with established
linting guidelines.
2026-02-20 15:36:01 +01:00
Martin Hauser
1b295f1d69 Closes #21473: Enable UP rules and modernize string formatting (#21488) 2026-02-19 10:25:08 -06: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
Jason Novinger
0b7375136d Closes #21016: Add missing MPTT tree indexes (#21432)
Upgrade django-mptt to 0.18.0 and add empty indexes tuple to MPTT model
Meta classes. The empty tuple triggers Django's migration detection for
indexes that django-mptt adds dynamically (see
django-mptt/django-mptt#682). We cannot define the indexes explicitly
because the MPTT fields don't exist when the Meta class is evaluated.

Affected models: Region, SiteGroup, Location, DeviceRole, Platform,
ModuleBay, InventoryItem, InventoryItemTemplate, TenantGroup,
ContactGroup, WirelessLANGroup
2026-02-13 17:00:04 +01: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
Martin Hauser
3a33df0e43 feat(forms): Add Owner Group support to Filter Forms
Introduces support for `owner_group` in various filter forms, improving
ownership granularity.
Updates DynamicModel fields to handle relationships
between `owner_group` and `owner` effectively.

Fixes #21081
2026-01-27 08:34:42 -05:00
Arthur
113c8b7ae6 merge feature 2025-12-09 10:39:48 -08:00
Jeremy Stretch
cc935dbfab Closes #20926: Rename and clean up GraphQL filters (#20935) 2025-12-08 13:40:43 -06:00
Arthur
7bf84eb400 update fields 2025-12-08 10:49:15 -08:00
Arthur
e910d461ea Add comments to OrganizationalModel 2025-12-08 09:46:38 -08: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
Brian Tiemann
5585b410f8 Remove all V1 files 2025-11-18 20:35:15 -05:00
Brian Tiemann
db3a4bc731 Incorporate Owner fields/types into V1 classes 2025-11-18 20:35:15 -05:00
Brian Tiemann
c7d94bd529 Change usages of FilterLookup to BaseFilterLookup 2025-11-18 20:35:13 -05:00
Brian Tiemann
a718cb1173 Convert all id fields and enum fields to FilterLookups (with in_list and exact support) 2025-11-18 20:34:37 -05:00
Brian Tiemann
867a01fae5 Clone all GraphQL objects to V1 versions 2025-11-18 20:34:25 -05:00
bctiemann
bcffc383bf Closes: #17936 - GFK serializer field (#20706)
* Establish GFKSerializerField and replace get_* methods in circuits.py

* Set read_only=True

* Apply GFKSerializerField to all matching SerializerMethodFields

* Use GFKSerializerField for ObjectChangeSerializer.changed_object and EventRuleSerializer.action_object
2025-11-04 10:01:22 -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
Martin Hauser
ac7a4ec4a3 feat(views): Add FilterSet support to BulkRenameView
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
2025-10-24 14:43:35 +02:00
Martin Hauser
f383067ecb Closes #20527: Address deprecation warnings (#20533) 2025-10-09 00:47:09 -05:00
Jeremy Stretch
bfd1adf0b5 Fixes #20441: Fix display of the "groups" column in contact assignments table (#20446) 2025-09-29 13:05:52 -05:00
Elliott Balsley
55cda3ca45 Fixes #20253: GraphQL filter by contacts (#20288)
* filter models by contacts

* remove unsed import

* simpler solution
2025-09-19 10:52:02 -04:00
Martin Hauser
8311f457b5 Fixes #20258: Correct typographical errors in labels (#20278) 2025-09-05 14:07:12 -05:00
Jeremy Stretch
40dd36812c Merge branch 'main' into feature 2025-07-31 15:24:33 -04:00
Jeremy Stretch
b610cf37cf Closes #19924: Record model features on ObjectType (#19939)
* Convert ObjectType to a concrete child model of ContentType

* Add public flag to ObjectType

* Catch post_migrate signal to update ObjectTypes

* Reference ObjectType records instead of registry for feature support

* Automatically create ObjectTypes

* Introduce has_feature() utility function

* ObjectTypeManager should not inherit from ContentTypeManager

* Misc cleanup

* Don't populate ObjectTypes during migration

* Don't automatically create ObjectTypes when a ContentType is created

* Fix test

* Extend has_feature() to accept a model or OT/CT

* Misc cleanup

* Deprecate get_for_id() on ObjectTypeManager

* Rename contenttypes.py to object_types.py

* Add index to features ArrayField

* Keep FK & M2M fields pointing to ContentType

* Add get_for_models() to ObjectTypeManager

* Add tests for manager methods & utility functions

* Fix migrations for M2M relations to ObjectType

* model_is_public() should return False for non-core & non-plugin models

* Order ObjectType by app_label & model name

* Resolve migrations conflict
2025-07-30 13:05:34 -04:00
Jason Novinger
26bec1275f Fixes #19934: add description field to Tenant bulk edit form (#19937) 2025-07-23 13:41:00 -07:00
Jeremy Stretch
5f8a4f6c43 Merge branch 'main' into feature 2025-07-16 09:52:58 -04:00
Jeremy Stretch
23cc4f1c41 Fixes #19839: Enable export of parent assignment for recursively nested objects 2025-07-10 12:41:11 -04:00
Jeremy Stretch
ce12de8b6d Closes #19231: Add bulk renaming support for all models (#19795)
* Closes #19231: Add bulk renaming support for all models

* Introduce a template filter for getattr()

* Extend BulkRenameView to support arbitrary field names

* Address bulk renaming support for remaining models

* Bulk rename URL resolution should fail silently

* Update documentation

* Fix bulk button rendering for HTMX requests
2025-07-02 13:35:34 -05:00
Jeremy Stretch
601a77ac73 Closes #19735: Implement reuable bulk operations classes (#19774)
* Initial work on #19735

* Work in progress

* Remove ClusterRemoveDevicesView (anti-pattern)

* Misc cleanup

* Fix has_bulk_actions

* Fix has_bulk_actions for ObjectChildrenView

* Restore clone button

* Misc cleanup

* Clean up custom bulk actions

* Rename individual object actions

* Collapse into a single template tag

* Fix support for legacy action dicts

* Rename bulk attr to multi

* clone_button tag should fail silently if view name is invalid

* Clean up action buttons

* Fix export button label

* Replace clone_button with an ObjectAction

* Create object actions for adding device/VM components

* Move core_sync.html to core app

* Remove extra_bulk_buttons from template doc
2025-06-30 13:03:07 -04:00
Jeremy Stretch
179c06ec20 Closes #19627: Object change migrators (#19628)
* Initial work on ObjectChange data migrations

* Fix migration bug

* Add migrators for MAC address assignments

* Update reverting kwarg; allow pop() to fail

* Cross-reference MAC address migrators

* Split migrator logic across migrations

* Add missing migrator
2025-06-05 11:47:59 -04:00
Jeremy Stretch
cf7ab43f39 Closes #19493: Change filter() to filter_type() (#19494) 2025-05-14 08:34:25 -07:00
bctiemann
6b9b5c4184 Merge pull request #19456 from netbox-community/19444-contact-groups-changelog
Fixes #19444: Fix change logging for contact group assignments
2025-05-13 11:39:59 -04:00
Jeremy Stretch
abeed474f6 Fixes #19444: Fix changeloggin for contact group assignments 2025-05-09 14:21:02 -04:00
Jeremy Stretch
76aa255f07 Fixes #19440: Ensure data migrations use the correct database connection 2025-05-08 14:53:52 -04:00
Jeremy Stretch
6e49cee718 Fixes #19376: Fix FieldDoesNotExist exception when global search results include a contact (#19389) 2025-05-02 14:24:08 -05:00
Jeremy Stretch
64b5867cb3 Merge branch 'main' into feature 2025-05-01 09:45:38 -04:00
Jeremy Stretch
37cfc50202 Fixes #19322: Correct URL paths for bulk import views (#19323) 2025-04-25 12:20:25 -05:00
bctiemann
cbcd91bf6b Merge pull request #19236 from netbox-community/19224-graphql-choices
Fixes #19224: Fix GraphQL API support for custom field choices
2025-04-22 09:35:55 -04:00
Jeremy Stretch
5121122350 Add missing GraphQL filters 2025-04-18 13:13:43 -04:00
Jeremy Stretch
4455c2c7dc Fixes #19224: Fix GraphQL API support for custom field choices 2025-04-17 12:22:14 -04:00
Arthur
978b5b0ed6 17170 ContactGroup Serializer nested and fix related objects 2025-04-11 15:13:40 -04:00
Jeremy Stretch
fc0acb020f Merge main into feature 2025-04-10 17:17:21 -04:00
Renato Almeida de Oliveira
864db469ba Fixes: #18305 make contacts mixin available for plugins (#19029) 2025-04-01 09:03:25 -04:00
Yi
b1d014b520 Fixes #18949: Add missing GraphQL ContactsMixin in types with ContactAssignments 2025-03-21 13:00:50 -05:00
Arthur Hanson
fe7cc8cae9 Closes #16224 GraphQL Pagination (#18903)
* 16244 add pagination

* 16244 add pagination

* 16244 fix order_by pagination

* 16224 document pagination

* 16224 remove extraneous code

* 16224 missing core types

* 16224 review changes

* 16224 review changes

* 16224 review changes
2025-03-20 15:00:14 -05:00
bctiemann
958dcca8d6 Fix migration conflict in tenancy (#18957) 2025-03-19 09:38:10 -05:00