Explorar o código

#19924: Expose public & features fields in API serializer and enable filtering

Jeremy Stretch hai 6 meses
pai
achega
70bd0cc9e2

+ 3 - 2
netbox/core/api/serializers_/object_types.py

@@ -26,9 +26,10 @@ class ObjectTypeSerializer(BaseModelSerializer):
     class Meta:
         model = ObjectType
         fields = [
-            'id', 'url', 'display', 'app_label', 'app_name', 'model', 'model_name', 'model_name_plural',
-            'is_plugin_model', 'rest_api_endpoint', 'description',
+            'id', 'url', 'display', 'app_label', 'app_name', 'model', 'model_name', 'model_name_plural', 'public',
+            'features', 'is_plugin_model', 'rest_api_endpoint', 'description',
         ]
+        read_only_fields = ['public', 'features']
 
     @extend_schema_field(OpenApiTypes.STR)
     def get_rest_api_endpoint(self, obj):

+ 8 - 2
netbox/core/filtersets.py

@@ -134,15 +134,18 @@ class JobFilterSet(BaseFilterSet):
         )
 
 
-class ObjectTypeFilterSet(django_filters.FilterSet):
+class ObjectTypeFilterSet(BaseFilterSet):
     q = django_filters.CharFilter(
         method='search',
         label=_('Search'),
     )
+    features = django_filters.CharFilter(
+        method='filter_features'
+    )
 
     class Meta:
         model = ObjectType
-        fields = ('id', 'app_label', 'model')
+        fields = ('id', 'app_label', 'model', 'public')
 
     def search(self, queryset, name, value):
         if not value.strip():
@@ -152,6 +155,9 @@ class ObjectTypeFilterSet(django_filters.FilterSet):
             Q(model__icontains=value)
         )
 
+    def filter_features(self, queryset, name, value):
+        return queryset.filter(features__icontains=value)
+
 
 class ObjectChangeFilterSet(BaseFilterSet):
     q = django_filters.CharFilter(

+ 45 - 0
netbox/core/tests/test_filtersets.py

@@ -241,3 +241,48 @@ class ObjectChangeTestCase(TestCase, BaseFilterSetTests):
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
         params = {'changed_object_type_id': [ContentType.objects.get(app_label='dcim', model='site').pk]}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
+
+
+class ObjectTypeTestCase(TestCase, BaseFilterSetTests):
+    queryset = ObjectType.objects.all()
+    filterset = ObjectTypeFilterSet
+    ignore_fields = (
+        'custom_fields',
+        'custom_links',
+        'event_rules',
+        'export_templates',
+        'object_permissions',
+        'saved_filters',
+    )
+
+    def test_q(self):
+        params = {'q': 'vrf'}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_app_label(self):
+        self.assertEqual(
+            self.filterset({'app_label': ['dcim']}, self.queryset).qs.count(),
+            ObjectType.objects.filter(app_label='dcim').count(),
+        )
+
+    def test_model(self):
+        self.assertEqual(
+            self.filterset({'model': ['site']}, self.queryset).qs.count(),
+            ObjectType.objects.filter(model='site').count(),
+        )
+
+    def test_public(self):
+        self.assertEqual(
+            self.filterset({'public': True}, self.queryset).qs.count(),
+            ObjectType.objects.filter(public=True).count(),
+        )
+        self.assertEqual(
+            self.filterset({'public': False}, self.queryset).qs.count(),
+            ObjectType.objects.filter(public=False).count(),
+        )
+
+    def test_feature(self):
+        self.assertEqual(
+            self.filterset({'features': 'tags'}, self.queryset).qs.count(),
+            ObjectType.objects.filter(features__contains=['tags']).count(),
+        )