Browse Source

Fixes: #18783 Add a tag_id filter for all models which support tagging (#18889)

Renato Almeida de Oliveira 10 months ago
parent
commit
9a1d9365cd

+ 21 - 0
docs/plugins/development/filtersets.md

@@ -61,6 +61,11 @@ class MyModelViewSet(...):
 
 The `TagFilter` class is available for all models which support tag assignment (those which inherit from `NetBoxModel` or `TagsMixin`). This filter subclasses django-filter's `ModelMultipleChoiceFilter` to work with NetBox's `TaggedItem` class.
 
+This class filters `tags` using the `slug` field. For example:
+
+`GET /api/dcim/sites/?tag=alpha&tag=bravo`
+
+
 ```python
 from django_filters import FilterSet
 from extras.filters import TagFilter
@@ -68,3 +73,19 @@ from extras.filters import TagFilter
 class MyModelFilterSet(FilterSet):
     tag = TagFilter()
 ```
+
+### TagIDFilter
+
+The `TagIDFilter` class is available for all models which support tag assignment (those which inherit from `NetBoxModel` or `TagsMixin`). This filter subclasses django-filter's `ModelMultipleChoiceFilter` to work with NetBox's `TaggedItem` class.
+
+This class filters `tags` using the `id` field. For example:
+
+`GET /api/dcim/sites/?tag_id=100&tag_id=200`
+
+```python
+from django_filters import FilterSet
+from extras.filters import TagIDFilter
+
+class MyModelFilterSet(FilterSet):
+    tag_id = TagIDFilter()
+```

+ 16 - 0
netbox/extras/filters.py

@@ -4,6 +4,7 @@ from .models import Tag
 
 __all__ = (
     'TagFilter',
+    'TagIDFilter',
 )
 
 
@@ -20,3 +21,18 @@ class TagFilter(django_filters.ModelMultipleChoiceFilter):
         kwargs.setdefault('queryset', Tag.objects.all())
 
         super().__init__(*args, **kwargs)
+
+
+class TagIDFilter(django_filters.ModelMultipleChoiceFilter):
+    """
+    Match on one or more assigned tags. If multiple tags are specified (e.g. ?tag=1&tag=2), the queryset is filtered
+    to objects matching all tags.
+    """
+    def __init__(self, *args, **kwargs):
+
+        kwargs.setdefault('field_name', 'tags__id')
+        kwargs.setdefault('to_field_name', 'id')
+        kwargs.setdefault('conjoined', True)
+        kwargs.setdefault('queryset', Tag.objects.all())
+
+        super().__init__(*args, **kwargs)

+ 2 - 1
netbox/extras/filtersets.py

@@ -11,7 +11,7 @@ from users.models import Group, User
 from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter
 from virtualization.models import Cluster, ClusterGroup, ClusterType
 from .choices import *
-from .filters import TagFilter
+from .filters import TagFilter, TagIDFilter
 from .models import *
 
 __all__ = (
@@ -665,6 +665,7 @@ class ConfigTemplateFilterSet(ChangeLoggedModelFilterSet):
         label=_('Data file (ID)'),
     )
     tag = TagFilter()
+    tag_id = TagIDFilter()
 
     class Meta:
         model = ConfigTemplate

+ 2 - 1
netbox/netbox/filtersets.py

@@ -10,7 +10,7 @@ from django.utils.translation import gettext as _
 from core.choices import ObjectChangeActionChoices
 from core.models import ObjectChange
 from extras.choices import CustomFieldFilterLogicChoices
-from extras.filters import TagFilter
+from extras.filters import TagFilter, TagIDFilter
 from extras.models import CustomField, SavedFilter
 from utilities.constants import (
     FILTER_CHAR_BASED_LOOKUP_MAP, FILTER_NEGATION_LOOKUP_MAP, FILTER_TREENODE_NEGATION_LOOKUP_MAP,
@@ -286,6 +286,7 @@ class NetBoxModelFilterSet(ChangeLoggedModelFilterSet):
         label=_('Search'),
     )
     tag = TagFilter()
+    tag_id = TagIDFilter()
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)