Преглед изворни кода

Closes #1792 - Add CustomFieldChoices API endpoint (#2941)

* Add new api endpoint for CustomFieldChoices

* Add changelog item for #1792

* Add tests for CustomFieldchoiceAPI endpoint
Grokzen пре 7 година
родитељ
комит
b9f4a9e57b
4 измењених фајлова са 70 додато и 3 уклоњено
  1. 1 0
      CHANGELOG.md
  2. 3 0
      netbox/extras/api/urls.py
  3. 34 2
      netbox/extras/api/views.py
  4. 32 1
      netbox/extras/tests/test_customfields.py

+ 1 - 0
CHANGELOG.md

@@ -22,6 +22,7 @@ to now use "Extras | Tag."
 * [#2643](https://github.com/digitalocean/netbox/issues/2643) - Add `description` field to console/power components and device bays
 * [#2791](https://github.com/digitalocean/netbox/issues/2791) - Add a comment field for tags
 * [#2926](https://github.com/digitalocean/netbox/issues/2926) - Add changelog to the Tag model
+* [#1792](https://github.com/digitalocean/netbox/issues/1792) - Add CustomFieldChoices API endpoint
 
 ---
 

+ 3 - 0
netbox/extras/api/urls.py

@@ -17,6 +17,9 @@ router.APIRootView = ExtrasRootView
 # Field choices
 router.register(r'_choices', views.ExtrasFieldChoicesViewSet, basename='field-choice')
 
+# Custom field choices
+router.register(r'_custom_field_choices', views.CustomFieldChoicesViewSet, base_name='custom-field-choice')
+
 # Graphs
 router.register(r'graphs', views.GraphViewSet)
 

+ 34 - 2
netbox/extras/api/views.py

@@ -1,3 +1,5 @@
+from collections import OrderedDict
+
 from django.contrib.contenttypes.models import ContentType
 from django.db.models import Count
 from django.http import Http404, HttpResponse
@@ -9,8 +11,8 @@ from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
 
 from extras import filters
 from extras.models import (
-    ConfigContext, CustomField, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, TopologyMap,
-    Tag
+    ConfigContext, CustomField, CustomFieldChoice, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, TopologyMap,
+    Tag,
 )
 from extras.reports import get_report, get_reports
 from utilities.api import FieldChoicesViewSet, IsAuthenticatedOrLoginNotRequired, ModelViewSet
@@ -28,6 +30,36 @@ class ExtrasFieldChoicesViewSet(FieldChoicesViewSet):
     )
 
 
+#
+# Custom field choices
+#
+
+class CustomFieldChoicesViewSet(ViewSet):
+    """
+    """
+    permission_classes = [IsAuthenticatedOrLoginNotRequired]
+
+    def __init__(self, *args, **kwargs):
+        super(CustomFieldChoicesViewSet, self).__init__(*args, **kwargs)
+
+        self._fields = OrderedDict()
+
+        for cfc in CustomFieldChoice.objects.all():
+            self._fields.setdefault(cfc.field.name, {})
+            self._fields[cfc.field.name][cfc.value] = cfc.pk
+
+    def list(self, request):
+        return Response(self._fields)
+
+    def retrieve(self, request, pk):
+        if pk not in self._fields:
+            raise Http404
+        return Response(self._fields[pk])
+
+    def get_view_name(self):
+        return "Custom Field choices"
+
+
 #
 # Custom fields
 #

+ 32 - 1
netbox/extras/tests/test_customfields.py

@@ -6,9 +6,10 @@ from django.urls import reverse
 from rest_framework import status
 
 from dcim.models import Site
-from extras.constants import CF_TYPE_TEXT, CF_TYPE_INTEGER, CF_TYPE_BOOLEAN, CF_TYPE_DATE, CF_TYPE_SELECT, CF_TYPE_URL
+from extras.constants import CF_TYPE_TEXT, CF_TYPE_INTEGER, CF_TYPE_BOOLEAN, CF_TYPE_DATE, CF_TYPE_SELECT, CF_TYPE_URL, CF_TYPE_SELECT
 from extras.models import CustomField, CustomFieldValue, CustomFieldChoice
 from utilities.testing import APITestCase
+from virtualization.models import VirtualMachine
 
 
 class CustomFieldTest(TestCase):
@@ -299,3 +300,33 @@ class CustomFieldAPITest(APITestCase):
         self.assertEqual(response.data['custom_fields'].get('magic_choice'), data['custom_fields']['magic_choice'])
         cfv = self.site.custom_field_values.get(field=self.cf_select)
         self.assertEqual(cfv.value.pk, data['custom_fields']['magic_choice'])
+
+
+class CustomFieldChoiceAPITest(APITestCase):
+    def setUp(self):
+        super().setUp()
+
+        vm_content_type = ContentType.objects.get_for_model(VirtualMachine)
+
+        self.cf_1 = CustomField.objects.create(name="cf_1", type=CF_TYPE_SELECT)
+        self.cf_2 = CustomField.objects.create(name="cf_2", type=CF_TYPE_SELECT)
+
+        self.cf_choice_1 = CustomFieldChoice.objects.create(field=self.cf_1, value="cf_field_1", weight=100)
+        self.cf_choice_2 = CustomFieldChoice.objects.create(field=self.cf_1, value="cf_field_2", weight=50)
+        self.cf_choice_3 = CustomFieldChoice.objects.create(field=self.cf_2, value="cf_field_3", weight=10)
+
+    def test_list_cfc(self):
+        url = reverse('extras-api:custom-field-choice-list')
+        response = self.client.get(url, **self.header)
+
+        self.assertEqual(len(response.data), 2)
+        self.assertEqual(len(response.data[self.cf_1.name]), 2)
+        self.assertEqual(len(response.data[self.cf_2.name]), 1)
+
+        self.assertTrue(self.cf_choice_1.value in response.data[self.cf_1.name])
+        self.assertTrue(self.cf_choice_2.value in response.data[self.cf_1.name])
+        self.assertTrue(self.cf_choice_3.value in response.data[self.cf_2.name])
+
+        self.assertEqual(self.cf_choice_1.pk, response.data[self.cf_1.name][self.cf_choice_1.value])
+        self.assertEqual(self.cf_choice_2.pk, response.data[self.cf_1.name][self.cf_choice_2.value])
+        self.assertEqual(self.cf_choice_3.pk, response.data[self.cf_2.name][self.cf_choice_3.value])