Skip to content

Commit 7a42cf8

Browse files
authored
Merge pull request #188 from netboxlabs/115-api-filtering
Fixes #115: Add support for REST API filtering
2 parents fffd763 + 1ecd49f commit 7a42cf8

File tree

3 files changed

+58
-65
lines changed

3 files changed

+58
-65
lines changed

netbox_custom_objects/api/views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from rest_framework.routers import APIRootView
33
from rest_framework.viewsets import ModelViewSet
44

5+
from netbox_custom_objects.filtersets import get_filterset_class
56
from netbox_custom_objects.models import CustomObjectType, CustomObjectTypeField
67

78
from . import serializers
@@ -39,6 +40,10 @@ def get_queryset(self):
3940
self.model = custom_object_type.get_model()
4041
return self.model.objects.all()
4142

43+
@property
44+
def filterset_class(self):
45+
return get_filterset_class(self.model)
46+
4247
def list(self, request, *args, **kwargs):
4348
return super().list(request, *args, **kwargs)
4449

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
from netbox.filtersets import NetBoxModelFilterSet
1+
import django_filters
2+
from django.contrib.postgres.fields import ArrayField
3+
from django.db.models import JSONField
4+
from netbox.filtersets import BaseFilterSet, NetBoxModelFilterSet
25

36
from .models import CustomObjectType
47

5-
__all__ = ("CustomObjectTypeFilterSet",)
8+
__all__ = (
9+
"CustomObjectTypeFilterSet",
10+
"get_filterset_class",
11+
)
612

713

814
class CustomObjectTypeFilterSet(NetBoxModelFilterSet):
@@ -14,18 +20,44 @@ class Meta:
1420
)
1521

1622

17-
"""
18-
class CustomObjectFilterSet(NetBoxModelFilterSet):
19-
class Meta:
20-
model = CustomObject
21-
fields = (
22-
"id",
23-
"name",
24-
"custom_object_type",
25-
)
23+
def get_filterset_class(model):
24+
"""
25+
Create and return a filterset class for the given custom object model.
26+
"""
27+
fields = [field.name for field in model._meta.fields]
28+
29+
meta = type(
30+
"Meta",
31+
(),
32+
{
33+
"model": model,
34+
"fields": fields,
35+
# TODO: overrides should come from FieldType
36+
# These are placeholders; should use different logic
37+
"filter_overrides": {
38+
JSONField: {
39+
"filter_class": django_filters.CharFilter,
40+
"extra": lambda f: {
41+
"lookup_expr": "icontains",
42+
},
43+
},
44+
ArrayField: {
45+
"filter_class": django_filters.CharFilter,
46+
"extra": lambda f: {
47+
"lookup_expr": "icontains",
48+
},
49+
},
50+
},
51+
},
52+
)
53+
54+
attrs = {
55+
"Meta": meta,
56+
"__module__": "database.filtersets",
57+
}
2658

27-
def search(self, queryset, name, value):
28-
if not value.strip():
29-
return queryset
30-
return queryset.filter(Q(name__icontains=value))
31-
"""
59+
return type(
60+
f"{model._meta.object_name}FilterSet",
61+
(BaseFilterSet,), # TODO: Should be a NetBoxModelFilterSet
62+
attrs,
63+
)

netbox_custom_objects/views.py

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import django_filters
21
import logging
2+
33
from core.models import ObjectChange
44
from core.tables import ObjectChangeTable
55
from django.contrib.contenttypes.models import ContentType
6-
from django.contrib.postgres.fields import ArrayField
7-
from django.db.models import JSONField, Q
6+
from django.db.models import Q
87
from django.shortcuts import get_object_or_404, render
98
from django.urls import reverse
109
from django.utils.translation import gettext_lazy as _
@@ -13,21 +12,15 @@
1312
from extras.forms import JournalEntryForm
1413
from extras.models import JournalEntry
1514
from extras.tables import JournalEntryTable
16-
from netbox.filtersets import BaseFilterSet
1715
from netbox.forms import NetBoxModelBulkEditForm, NetBoxModelFilterSetForm
1816
from netbox.views import generic
1917
from netbox.views.generic.mixins import TableMixin
2018
from utilities.forms import ConfirmationForm
2119
from utilities.htmx import htmx_partial
22-
from utilities.views import (
23-
ConditionalLoginRequiredMixin,
24-
ViewTab,
25-
get_viewname,
26-
register_model_view,
27-
)
20+
from utilities.views import ConditionalLoginRequiredMixin, ViewTab, get_viewname, register_model_view
2821

22+
from netbox_custom_objects.filtersets import get_filterset_class
2923
from netbox_custom_objects.tables import CustomObjectTable
30-
3124
from . import field_types, filtersets, forms, tables
3225
from .models import CustomObject, CustomObjectType, CustomObjectTypeField
3326

@@ -324,44 +317,7 @@ def get_queryset(self, request):
324317
return model.objects.all()
325318

326319
def get_filterset(self):
327-
model = self.queryset.model
328-
fields = [field.name for field in model._meta.fields]
329-
330-
meta = type(
331-
"Meta",
332-
(),
333-
{
334-
"model": model,
335-
"fields": fields,
336-
# TODO: overrides should come from FieldType
337-
# These are placeholders; should use different logic
338-
"filter_overrides": {
339-
JSONField: {
340-
"filter_class": django_filters.CharFilter,
341-
"extra": lambda f: {
342-
"lookup_expr": "icontains",
343-
},
344-
},
345-
ArrayField: {
346-
"filter_class": django_filters.CharFilter,
347-
"extra": lambda f: {
348-
"lookup_expr": "icontains",
349-
},
350-
},
351-
},
352-
},
353-
)
354-
355-
attrs = {
356-
"Meta": meta,
357-
"__module__": "database.filtersets",
358-
}
359-
360-
return type(
361-
f"{model._meta.object_name}FilterSet",
362-
(BaseFilterSet,), # TODO: Should be a NetBoxModelFilterSet
363-
attrs,
364-
)
320+
return get_filterset_class(self.queryset.model)
365321

366322
def get_filterset_form(self):
367323
model = self.queryset.model

0 commit comments

Comments
 (0)