mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #1556: Added API endpoints listing static field choices for each app
This commit is contained in:
@ -16,6 +16,9 @@ class CircuitsRootView(routers.APIRootView):
|
|||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.APIRootView = CircuitsRootView
|
router.APIRootView = CircuitsRootView
|
||||||
|
|
||||||
|
# Field choices
|
||||||
|
router.register(r'_choices', views.CircuitsFieldChoicesViewSet, base_name='field-choice')
|
||||||
|
|
||||||
# Providers
|
# Providers
|
||||||
router.register(r'providers', views.ProviderViewSet)
|
router.register(r'providers', views.ProviderViewSet)
|
||||||
|
|
||||||
|
@ -11,10 +11,20 @@ from circuits.models import Provider, CircuitTermination, CircuitType, Circuit
|
|||||||
from extras.models import Graph, GRAPH_TYPE_PROVIDER
|
from extras.models import Graph, GRAPH_TYPE_PROVIDER
|
||||||
from extras.api.serializers import RenderedGraphSerializer
|
from extras.api.serializers import RenderedGraphSerializer
|
||||||
from extras.api.views import CustomFieldModelViewSet
|
from extras.api.views import CustomFieldModelViewSet
|
||||||
from utilities.api import WritableSerializerMixin
|
from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Field choices
|
||||||
|
#
|
||||||
|
|
||||||
|
class CircuitsFieldChoicesViewSet(FieldChoicesViewSet):
|
||||||
|
fields = (
|
||||||
|
(CircuitTermination, ['term_side']),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Providers
|
# Providers
|
||||||
#
|
#
|
||||||
|
@ -16,6 +16,9 @@ class DCIMRootView(routers.APIRootView):
|
|||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.APIRootView = DCIMRootView
|
router.APIRootView = DCIMRootView
|
||||||
|
|
||||||
|
# Field choices
|
||||||
|
router.register(r'_choices', views.DCIMFieldChoicesViewSet, base_name='field-choice')
|
||||||
|
|
||||||
# Sites
|
# Sites
|
||||||
router.register(r'regions', views.RegionViewSet)
|
router.register(r'regions', views.RegionViewSet)
|
||||||
router.register(r'sites', views.SiteViewSet)
|
router.register(r'sites', views.SiteViewSet)
|
||||||
|
@ -20,11 +20,27 @@ from dcim import filters
|
|||||||
from extras.api.serializers import RenderedGraphSerializer
|
from extras.api.serializers import RenderedGraphSerializer
|
||||||
from extras.api.views import CustomFieldModelViewSet
|
from extras.api.views import CustomFieldModelViewSet
|
||||||
from extras.models import Graph, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE
|
from extras.models import Graph, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE
|
||||||
from utilities.api import IsAuthenticatedOrLoginNotRequired, ServiceUnavailable, WritableSerializerMixin
|
from utilities.api import IsAuthenticatedOrLoginNotRequired, FieldChoicesViewSet, ServiceUnavailable, WritableSerializerMixin
|
||||||
from .exceptions import MissingFilterException
|
from .exceptions import MissingFilterException
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Field choices
|
||||||
|
#
|
||||||
|
|
||||||
|
class DCIMFieldChoicesViewSet(FieldChoicesViewSet):
|
||||||
|
fields = (
|
||||||
|
(Device, ['face', 'status']),
|
||||||
|
(ConsolePort, ['connection_status']),
|
||||||
|
(Interface, ['form_factor']),
|
||||||
|
(InterfaceConnection, ['connection_status']),
|
||||||
|
(InterfaceTemplate, ['form_factor']),
|
||||||
|
(PowerPort, ['connection_status']),
|
||||||
|
(Rack, ['type', 'width']),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Regions
|
# Regions
|
||||||
#
|
#
|
||||||
|
@ -16,6 +16,9 @@ class ExtrasRootView(routers.APIRootView):
|
|||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.APIRootView = ExtrasRootView
|
router.APIRootView = ExtrasRootView
|
||||||
|
|
||||||
|
# Field choices
|
||||||
|
router.register(r'_choices', views.ExtrasFieldChoicesViewSet, base_name='field-choice')
|
||||||
|
|
||||||
# Graphs
|
# Graphs
|
||||||
router.register(r'graphs', views.GraphViewSet)
|
router.register(r'graphs', views.GraphViewSet)
|
||||||
|
|
||||||
|
@ -10,12 +10,27 @@ from django.http import Http404, HttpResponse
|
|||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
from extras import filters
|
from extras import filters
|
||||||
from extras.models import ExportTemplate, Graph, ImageAttachment, ReportResult, TopologyMap, UserAction
|
from extras.models import CustomField, ExportTemplate, Graph, ImageAttachment, ReportResult, TopologyMap, UserAction
|
||||||
from extras.reports import get_report, get_reports
|
from extras.reports import get_report, get_reports
|
||||||
from utilities.api import WritableSerializerMixin
|
from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Field choices
|
||||||
|
#
|
||||||
|
|
||||||
|
class ExtrasFieldChoicesViewSet(FieldChoicesViewSet):
|
||||||
|
fields = (
|
||||||
|
(CustomField, ['type']),
|
||||||
|
(Graph, ['type']),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Custom fields
|
||||||
|
#
|
||||||
|
|
||||||
class CustomFieldModelViewSet(ModelViewSet):
|
class CustomFieldModelViewSet(ModelViewSet):
|
||||||
"""
|
"""
|
||||||
Include the applicable set of CustomFields in the ModelViewSet context.
|
Include the applicable set of CustomFields in the ModelViewSet context.
|
||||||
@ -46,6 +61,10 @@ class CustomFieldModelViewSet(ModelViewSet):
|
|||||||
return super(CustomFieldModelViewSet, self).get_queryset().prefetch_related('custom_field_values__field')
|
return super(CustomFieldModelViewSet, self).get_queryset().prefetch_related('custom_field_values__field')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Graphs
|
||||||
|
#
|
||||||
|
|
||||||
class GraphViewSet(WritableSerializerMixin, ModelViewSet):
|
class GraphViewSet(WritableSerializerMixin, ModelViewSet):
|
||||||
queryset = Graph.objects.all()
|
queryset = Graph.objects.all()
|
||||||
serializer_class = serializers.GraphSerializer
|
serializer_class = serializers.GraphSerializer
|
||||||
@ -53,12 +72,20 @@ class GraphViewSet(WritableSerializerMixin, ModelViewSet):
|
|||||||
filter_class = filters.GraphFilter
|
filter_class = filters.GraphFilter
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Export templates
|
||||||
|
#
|
||||||
|
|
||||||
class ExportTemplateViewSet(WritableSerializerMixin, ModelViewSet):
|
class ExportTemplateViewSet(WritableSerializerMixin, ModelViewSet):
|
||||||
queryset = ExportTemplate.objects.all()
|
queryset = ExportTemplate.objects.all()
|
||||||
serializer_class = serializers.ExportTemplateSerializer
|
serializer_class = serializers.ExportTemplateSerializer
|
||||||
filter_class = filters.ExportTemplateFilter
|
filter_class = filters.ExportTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Topology maps
|
||||||
|
#
|
||||||
|
|
||||||
class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet):
|
class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet):
|
||||||
queryset = TopologyMap.objects.select_related('site')
|
queryset = TopologyMap.objects.select_related('site')
|
||||||
serializer_class = serializers.TopologyMapSerializer
|
serializer_class = serializers.TopologyMapSerializer
|
||||||
@ -85,12 +112,20 @@ class TopologyMapViewSet(WritableSerializerMixin, ModelViewSet):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Image attachments
|
||||||
|
#
|
||||||
|
|
||||||
class ImageAttachmentViewSet(WritableSerializerMixin, ModelViewSet):
|
class ImageAttachmentViewSet(WritableSerializerMixin, ModelViewSet):
|
||||||
queryset = ImageAttachment.objects.all()
|
queryset = ImageAttachment.objects.all()
|
||||||
serializer_class = serializers.ImageAttachmentSerializer
|
serializer_class = serializers.ImageAttachmentSerializer
|
||||||
write_serializer_class = serializers.WritableImageAttachmentSerializer
|
write_serializer_class = serializers.WritableImageAttachmentSerializer
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Reports
|
||||||
|
#
|
||||||
|
|
||||||
class ReportViewSet(ViewSet):
|
class ReportViewSet(ViewSet):
|
||||||
_ignore_model_permissions = True
|
_ignore_model_permissions = True
|
||||||
exclude_from_schema = True
|
exclude_from_schema = True
|
||||||
@ -162,6 +197,10 @@ class ReportViewSet(ViewSet):
|
|||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# User activity
|
||||||
|
#
|
||||||
|
|
||||||
class RecentActivityViewSet(ReadOnlyModelViewSet):
|
class RecentActivityViewSet(ReadOnlyModelViewSet):
|
||||||
"""
|
"""
|
||||||
List all UserActions to provide a log of recent activity.
|
List all UserActions to provide a log of recent activity.
|
||||||
|
@ -16,6 +16,9 @@ class IPAMRootView(routers.APIRootView):
|
|||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.APIRootView = IPAMRootView
|
router.APIRootView = IPAMRootView
|
||||||
|
|
||||||
|
# Field choices
|
||||||
|
router.register(r'_choices', views.IPAMFieldChoicesViewSet, base_name='field-choice')
|
||||||
|
|
||||||
# VRFs
|
# VRFs
|
||||||
router.register(r'vrfs', views.VRFViewSet)
|
router.register(r'vrfs', views.VRFViewSet)
|
||||||
|
|
||||||
|
@ -12,10 +12,24 @@ from django.shortcuts import get_object_or_404
|
|||||||
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
|
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
|
||||||
from ipam import filters
|
from ipam import filters
|
||||||
from extras.api.views import CustomFieldModelViewSet
|
from extras.api.views import CustomFieldModelViewSet
|
||||||
from utilities.api import WritableSerializerMixin
|
from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Field choices
|
||||||
|
#
|
||||||
|
|
||||||
|
class IPAMFieldChoicesViewSet(FieldChoicesViewSet):
|
||||||
|
fields = (
|
||||||
|
(Aggregate, ['family']),
|
||||||
|
(Prefix, ['family', 'status']),
|
||||||
|
(IPAddress, ['family', 'status', 'role']),
|
||||||
|
(VLAN, ['status']),
|
||||||
|
(Service, ['protocol']),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# VRFs
|
# VRFs
|
||||||
#
|
#
|
||||||
|
@ -16,6 +16,9 @@ class SecretsRootView(routers.APIRootView):
|
|||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.APIRootView = SecretsRootView
|
router.APIRootView = SecretsRootView
|
||||||
|
|
||||||
|
# Field choices
|
||||||
|
router.register(r'_choices', views.SecretsFieldChoicesViewSet, base_name='field-choice')
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
router.register(r'secret-roles', views.SecretRoleViewSet)
|
router.register(r'secret-roles', views.SecretRoleViewSet)
|
||||||
router.register(r'secrets', views.SecretViewSet)
|
router.register(r'secrets', views.SecretViewSet)
|
||||||
|
@ -12,7 +12,7 @@ from django.http import HttpResponseBadRequest
|
|||||||
from secrets import filters
|
from secrets import filters
|
||||||
from secrets.exceptions import InvalidKey
|
from secrets.exceptions import InvalidKey
|
||||||
from secrets.models import Secret, SecretRole, SessionKey, UserKey
|
from secrets.models import Secret, SecretRole, SessionKey, UserKey
|
||||||
from utilities.api import WritableSerializerMixin
|
from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
@ -22,6 +22,14 @@ ERR_PRIVKEY_MISSING = "Private key was not provided."
|
|||||||
ERR_PRIVKEY_INVALID = "Invalid private key."
|
ERR_PRIVKEY_INVALID = "Invalid private key."
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Field choices
|
||||||
|
#
|
||||||
|
|
||||||
|
class SecretsFieldChoicesViewSet(FieldChoicesViewSet):
|
||||||
|
fields = ()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Secret Roles
|
# Secret Roles
|
||||||
#
|
#
|
||||||
|
@ -16,6 +16,9 @@ class TenancyRootView(routers.APIRootView):
|
|||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.APIRootView = TenancyRootView
|
router.APIRootView = TenancyRootView
|
||||||
|
|
||||||
|
# Field choices
|
||||||
|
router.register(r'_choices', views.TenancyFieldChoicesViewSet, base_name='field-choice')
|
||||||
|
|
||||||
# Tenants
|
# Tenants
|
||||||
router.register(r'tenant-groups', views.TenantGroupViewSet)
|
router.register(r'tenant-groups', views.TenantGroupViewSet)
|
||||||
router.register(r'tenants', views.TenantViewSet)
|
router.register(r'tenants', views.TenantViewSet)
|
||||||
|
@ -5,10 +5,18 @@ from rest_framework.viewsets import ModelViewSet
|
|||||||
from extras.api.views import CustomFieldModelViewSet
|
from extras.api.views import CustomFieldModelViewSet
|
||||||
from tenancy import filters
|
from tenancy import filters
|
||||||
from tenancy.models import Tenant, TenantGroup
|
from tenancy.models import Tenant, TenantGroup
|
||||||
from utilities.api import WritableSerializerMixin
|
from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Field choices
|
||||||
|
#
|
||||||
|
|
||||||
|
class TenancyFieldChoicesViewSet(FieldChoicesViewSet):
|
||||||
|
fields = ()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Tenant Groups
|
# Tenant Groups
|
||||||
#
|
#
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.http import Http404
|
||||||
|
|
||||||
from rest_framework.compat import is_authenticated
|
from rest_framework.compat import is_authenticated
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
from rest_framework.permissions import BasePermission
|
from rest_framework.permissions import BasePermission
|
||||||
|
from rest_framework.response import Response
|
||||||
from rest_framework.serializers import Field, ModelSerializer, ValidationError
|
from rest_framework.serializers import Field, ModelSerializer, ValidationError
|
||||||
|
from rest_framework.viewsets import ViewSet
|
||||||
|
|
||||||
|
|
||||||
WRITE_OPERATIONS = ['create', 'update', 'partial_update', 'delete']
|
WRITE_OPERATIONS = ['create', 'update', 'partial_update', 'delete']
|
||||||
@ -94,6 +98,55 @@ class ContentTypeFieldSerializer(Field):
|
|||||||
raise ValidationError("Invalid content type")
|
raise ValidationError("Invalid content type")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Views
|
||||||
|
#
|
||||||
|
|
||||||
|
class FieldChoicesViewSet(ViewSet):
|
||||||
|
"""
|
||||||
|
Expose the built-in numeric values which represent static choices for a model's field.
|
||||||
|
"""
|
||||||
|
permission_classes = [IsAuthenticatedOrLoginNotRequired]
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(FieldChoicesViewSet, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
# Compile a dict of all fields in this view
|
||||||
|
self._fields = OrderedDict()
|
||||||
|
for cls, field_list in self.fields:
|
||||||
|
for field_name in field_list:
|
||||||
|
model_name = cls._meta.verbose_name.lower().replace(' ', '-')
|
||||||
|
key = ':'.join([model_name, field_name])
|
||||||
|
choices = []
|
||||||
|
for k, v in cls._meta.get_field(field_name).choices:
|
||||||
|
if type(v) in [list, tuple]:
|
||||||
|
for k2, v2 in v:
|
||||||
|
choices.append({
|
||||||
|
'value': v2,
|
||||||
|
'label': k2,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
choices.append({
|
||||||
|
'value': v,
|
||||||
|
'label': k,
|
||||||
|
})
|
||||||
|
self._fields[key] = choices
|
||||||
|
|
||||||
|
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 "Field Choices"
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Mixins
|
# Mixins
|
||||||
#
|
#
|
||||||
|
@ -16,6 +16,9 @@ class VirtualizationRootView(routers.APIRootView):
|
|||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.APIRootView = VirtualizationRootView
|
router.APIRootView = VirtualizationRootView
|
||||||
|
|
||||||
|
# Field choices
|
||||||
|
router.register(r'_choices', views.VirtualizationFieldChoicesViewSet, base_name='field-choice')
|
||||||
|
|
||||||
# Clusters
|
# Clusters
|
||||||
router.register(r'cluster-types', views.ClusterTypeViewSet)
|
router.register(r'cluster-types', views.ClusterTypeViewSet)
|
||||||
router.register(r'cluster-groups', views.ClusterGroupViewSet)
|
router.register(r'cluster-groups', views.ClusterGroupViewSet)
|
||||||
|
@ -4,12 +4,22 @@ from rest_framework.viewsets import ModelViewSet
|
|||||||
|
|
||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
from extras.api.views import CustomFieldModelViewSet
|
from extras.api.views import CustomFieldModelViewSet
|
||||||
from utilities.api import WritableSerializerMixin
|
from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
|
||||||
from virtualization import filters
|
from virtualization import filters
|
||||||
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Field choices
|
||||||
|
#
|
||||||
|
|
||||||
|
class VirtualizationFieldChoicesViewSet(FieldChoicesViewSet):
|
||||||
|
fields = (
|
||||||
|
(VirtualMachine, ['status']),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Clusters
|
# Clusters
|
||||||
#
|
#
|
||||||
|
Reference in New Issue
Block a user