Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/plugins/development/filtersets.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,31 @@ 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

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 changes: 16 additions & 0 deletions netbox/extras/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

__all__ = (
'TagFilter',
'TagIDFilter',
)


Expand All @@ -20,3 +21,18 @@ def __init__(self, *args, **kwargs):
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)
3 changes: 2 additions & 1 deletion netbox/extras/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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__ = (
Expand Down Expand Up @@ -665,6 +665,7 @@ class ConfigTemplateFilterSet(ChangeLoggedModelFilterSet):
label=_('Data file (ID)'),
)
tag = TagFilter()
tag_id = TagIDFilter()

class Meta:
model = ConfigTemplate
Expand Down
3 changes: 2 additions & 1 deletion netbox/netbox/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
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,
Expand Down Expand Up @@ -286,6 +286,7 @@ class NetBoxModelFilterSet(ChangeLoggedModelFilterSet):
label=_('Search'),
)
tag = TagFilter()
tag_id = TagIDFilter()

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down