mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-10 18:39:36 -06:00
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.
This commit is contained in:
parent
5664684530
commit
ee6a3a495b
@ -295,6 +295,7 @@ class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
|
||||
|
||||
@register_filterset(TableConfigFilterSet)
|
||||
class TableConfigFilterForm(SavedFiltersMixin, FilterForm):
|
||||
model = TableConfig
|
||||
fieldsets = (
|
||||
FieldSet('q', 'filter_id'),
|
||||
FieldSet('object_type_id', 'enabled', 'shared', 'weight', name=_('Attributes')),
|
||||
|
||||
@ -6,18 +6,14 @@ from .utils import *
|
||||
|
||||
def register_filterset(filterset_class):
|
||||
"""
|
||||
Decorator for registering a FilterForm -> FilterSet mapping.
|
||||
Decorator for registering a FilterSet with the application registry.
|
||||
|
||||
Usage:
|
||||
@register_filterset(DeviceFilterSet)
|
||||
class DeviceFilterForm(NetBoxModelFilterSetForm):
|
||||
...
|
||||
|
||||
Args:
|
||||
filterset_class: The corresponding filterset class
|
||||
Uses model identifier as key to match search index pattern.
|
||||
"""
|
||||
def decorator(form_class):
|
||||
from netbox.registry import registry
|
||||
registry['filtersets'][form_class] = filterset_class
|
||||
model = filterset_class._meta.model
|
||||
key = f'{model._meta.app_label}.{model._meta.model_name}'
|
||||
registry['filtersets'][key] = filterset_class
|
||||
return form_class
|
||||
return decorator
|
||||
|
||||
@ -176,14 +176,20 @@ class FilterModifierMixin:
|
||||
from utilities.forms.widgets import FilterModifierWidget
|
||||
from netbox.registry import registry
|
||||
|
||||
# Get the corresponding FilterSet if registered
|
||||
filterset_class = registry['filtersets'].get(self.__class__)
|
||||
model = getattr(self, 'model', None)
|
||||
if model is None and hasattr(self, '_meta'):
|
||||
model = getattr(self._meta, 'model', None)
|
||||
|
||||
filterset_class = None
|
||||
if model:
|
||||
key = f'{model._meta.app_label}.{model._meta.model_name}'
|
||||
filterset_class = registry['filtersets'].get(key)
|
||||
|
||||
filterset = filterset_class() if filterset_class else None
|
||||
|
||||
for field_name, field in self.fields.items():
|
||||
lookups = self._get_lookup_choices(field)
|
||||
|
||||
# Verify lookups against FilterSet if available
|
||||
if filterset:
|
||||
lookups = self._verify_lookups_with_filterset(field_name, lookups, filterset)
|
||||
|
||||
@ -198,24 +204,19 @@ class FilterModifierMixin:
|
||||
|
||||
Returns an empty list for fields that should not be enhanced.
|
||||
"""
|
||||
# Skip query/search fields
|
||||
if isinstance(field, QueryField):
|
||||
return []
|
||||
|
||||
# Skip boolean fields (no benefit from modifiers)
|
||||
if isinstance(field, (forms.BooleanField, forms.NullBooleanField)):
|
||||
return []
|
||||
|
||||
# Skip API widget fields
|
||||
if self._is_api_widget_field(field):
|
||||
return []
|
||||
|
||||
# Walk up the MRO to find a known field type
|
||||
for field_class in field.__class__.__mro__:
|
||||
if field_class in FORM_FIELD_LOOKUPS:
|
||||
return FORM_FIELD_LOOKUPS[field_class]
|
||||
|
||||
# Unknown field type - return empty list (no enhancement)
|
||||
return []
|
||||
|
||||
def _verify_lookups_with_filterset(self, field_name, lookups, filterset):
|
||||
@ -223,13 +224,11 @@ class FilterModifierMixin:
|
||||
verified_lookups = []
|
||||
|
||||
for lookup_code, lookup_label in lookups:
|
||||
# Handle special empty_true/false codes that map to __empty
|
||||
if lookup_code in (MODIFIER_EMPTY_TRUE, MODIFIER_EMPTY_FALSE):
|
||||
filter_key = f'{field_name}__empty'
|
||||
else:
|
||||
filter_key = f'{field_name}__{lookup_code}' if lookup_code != 'exact' else field_name
|
||||
|
||||
# Check if this filter exists in the FilterSet
|
||||
if filter_key in filterset.filters:
|
||||
verified_lookups.append((lookup_code, lookup_label))
|
||||
|
||||
@ -237,11 +236,9 @@ class FilterModifierMixin:
|
||||
|
||||
def _is_api_widget_field(self, field):
|
||||
"""Check if a field uses an API-based widget."""
|
||||
# Check field class name
|
||||
if 'Dynamic' in field.__class__.__name__:
|
||||
return True
|
||||
|
||||
# Check widget attributes for API-related data
|
||||
if hasattr(field.widget, 'attrs') and field.widget.attrs:
|
||||
api_attrs = ['data-url', 'data-api-url', 'data-static-params']
|
||||
if any(attr in field.widget.attrs for attr in api_attrs):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user