Merge pull request #19236 from netbox-community/19224-graphql-choices

Fixes #19224: Fix GraphQL API support for custom field choices
This commit is contained in:
bctiemann 2025-04-22 09:35:55 -04:00 committed by GitHub
commit cbcd91bf6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 82 additions and 81 deletions

View File

@ -4,17 +4,13 @@ from circuits.choices import *
__all__ = (
'CircuitStatusEnum',
'CircuitCommitRateEnum',
'CircuitTerminationSideEnum',
'CircuitTerminationPortSpeedEnum',
'CircuitPriorityEnum',
'VirtualCircuitTerminationRoleEnum',
)
CircuitCommitRateEnum = strawberry.enum(CircuitCommitRateChoices.as_enum())
CircuitPriorityEnum = strawberry.enum(CircuitPriorityChoices.as_enum())
CircuitStatusEnum = strawberry.enum(CircuitStatusChoices.as_enum())
CircuitTerminationSideEnum = strawberry.enum(CircuitTerminationSideChoices.as_enum())
CircuitTerminationPortSpeedEnum = strawberry.enum(CircuitTerminationPortSpeedChoices.as_enum())
VirtualCircuitTerminationRoleEnum = strawberry.enum(VirtualCircuitTerminationRoleChoices.as_enum())
CircuitPriorityEnum = strawberry.enum(CircuitPriorityChoices.as_enum(prefix='priority'))
CircuitStatusEnum = strawberry.enum(CircuitStatusChoices.as_enum('status'))
CircuitTerminationSideEnum = strawberry.enum(CircuitTerminationSideChoices.as_enum(prefix='side'))
VirtualCircuitTerminationRoleEnum = strawberry.enum(VirtualCircuitTerminationRoleChoices.as_enum(prefix='role'))

View File

@ -15,7 +15,6 @@ __all__ = (
'InterfaceModeEnum',
'InterfacePoEModeEnum',
'InterfacePoETypeEnum',
'InterfaceSpeedEnum',
'InterfaceTypeEnum',
'InventoryItemStatusEnum',
'LinkStatusEnum',
@ -40,38 +39,37 @@ __all__ = (
'VirtualDeviceContextStatusEnum',
)
CableEndEnum = strawberry.enum(CableEndChoices.as_enum())
CableLengthUnitEnum = strawberry.enum(CableLengthUnitChoices.as_enum())
CableTypeEnum = strawberry.enum(CableTypeChoices.as_enum())
ConsolePortSpeedEnum = strawberry.enum(ConsolePortSpeedChoices.as_enum())
ConsolePortTypeEnum = strawberry.enum(ConsolePortTypeChoices.as_enum())
DeviceAirflowEnum = strawberry.enum(DeviceAirflowChoices.as_enum())
DeviceFaceEnum = strawberry.enum(DeviceFaceChoices.as_enum())
DeviceStatusEnum = strawberry.enum(DeviceStatusChoices.as_enum())
InterfaceDuplexEnum = strawberry.enum(InterfaceDuplexChoices.as_enum())
InterfaceModeEnum = strawberry.enum(InterfaceModeChoices.as_enum())
InterfacePoEModeEnum = strawberry.enum(InterfacePoEModeChoices.as_enum())
CableEndEnum = strawberry.enum(CableEndChoices.as_enum(prefix='side'))
CableLengthUnitEnum = strawberry.enum(CableLengthUnitChoices.as_enum(prefix='unit'))
CableTypeEnum = strawberry.enum(CableTypeChoices.as_enum(prefix='type'))
ConsolePortSpeedEnum = strawberry.enum(ConsolePortSpeedChoices.as_enum(prefix='speed'))
ConsolePortTypeEnum = strawberry.enum(ConsolePortTypeChoices.as_enum(prefix='type'))
DeviceAirflowEnum = strawberry.enum(DeviceAirflowChoices.as_enum(prefix='airflow'))
DeviceFaceEnum = strawberry.enum(DeviceFaceChoices.as_enum(prefix='face'))
DeviceStatusEnum = strawberry.enum(DeviceStatusChoices.as_enum(prefix='status'))
InterfaceDuplexEnum = strawberry.enum(InterfaceDuplexChoices.as_enum(prefix='duplex'))
InterfaceModeEnum = strawberry.enum(InterfaceModeChoices.as_enum(prefix='mode'))
InterfacePoEModeEnum = strawberry.enum(InterfacePoEModeChoices.as_enum(prefix='mode'))
InterfacePoETypeEnum = strawberry.enum(InterfacePoETypeChoices.as_enum())
InterfaceSpeedEnum = strawberry.enum(InterfaceSpeedChoices.as_enum())
InterfaceTypeEnum = strawberry.enum(InterfaceTypeChoices.as_enum())
InventoryItemStatusEnum = strawberry.enum(InventoryItemStatusChoices.as_enum())
LinkStatusEnum = strawberry.enum(LinkStatusChoices.as_enum())
LocationStatusEnum = strawberry.enum(LocationStatusChoices.as_enum())
InterfaceTypeEnum = strawberry.enum(InterfaceTypeChoices.as_enum(prefix='type'))
InventoryItemStatusEnum = strawberry.enum(InventoryItemStatusChoices.as_enum(prefix='status'))
LinkStatusEnum = strawberry.enum(LinkStatusChoices.as_enum(prefix='status'))
LocationStatusEnum = strawberry.enum(LocationStatusChoices.as_enum(prefix='status'))
ModuleAirflowEnum = strawberry.enum(ModuleAirflowChoices.as_enum())
ModuleStatusEnum = strawberry.enum(ModuleStatusChoices.as_enum())
PortTypeEnum = strawberry.enum(PortTypeChoices.as_enum())
PowerFeedPhaseEnum = strawberry.enum(PowerFeedPhaseChoices.as_enum())
PowerFeedStatusEnum = strawberry.enum(PowerFeedStatusChoices.as_enum())
PowerFeedSupplyEnum = strawberry.enum(PowerFeedSupplyChoices.as_enum())
PowerFeedTypeEnum = strawberry.enum(PowerFeedTypeChoices.as_enum())
PowerOutletFeedLegEnum = strawberry.enum(PowerOutletFeedLegChoices.as_enum())
PowerOutletTypeEnum = strawberry.enum(PowerOutletTypeChoices.as_enum())
PowerPortTypeEnum = strawberry.enum(PowerPortTypeChoices.as_enum())
ModuleStatusEnum = strawberry.enum(ModuleStatusChoices.as_enum(prefix='status'))
PortTypeEnum = strawberry.enum(PortTypeChoices.as_enum(prefix='type'))
PowerFeedPhaseEnum = strawberry.enum(PowerFeedPhaseChoices.as_enum(prefix='phase'))
PowerFeedStatusEnum = strawberry.enum(PowerFeedStatusChoices.as_enum(prefix='status'))
PowerFeedSupplyEnum = strawberry.enum(PowerFeedSupplyChoices.as_enum(prefix='supply'))
PowerFeedTypeEnum = strawberry.enum(PowerFeedTypeChoices.as_enum(prefix='type'))
PowerOutletFeedLegEnum = strawberry.enum(PowerOutletFeedLegChoices.as_enum(prefix='feed_leg'))
PowerOutletTypeEnum = strawberry.enum(PowerOutletTypeChoices.as_enum(prefix='type'))
PowerPortTypeEnum = strawberry.enum(PowerPortTypeChoices.as_enum(prefix='type'))
RackAirflowEnum = strawberry.enum(RackAirflowChoices.as_enum())
RackDimensionUnitEnum = strawberry.enum(RackDimensionUnitChoices.as_enum())
RackFormFactorEnum = strawberry.enum(RackFormFactorChoices.as_enum())
RackStatusEnum = strawberry.enum(RackStatusChoices.as_enum())
RackWidthEnum = strawberry.enum(RackWidthChoices.as_enum())
SiteStatusEnum = strawberry.enum(SiteStatusChoices.as_enum())
SubdeviceRoleEnum = strawberry.enum(SubdeviceRoleChoices.as_enum())
VirtualDeviceContextStatusEnum = strawberry.enum(VirtualDeviceContextStatusChoices.as_enum())
RackDimensionUnitEnum = strawberry.enum(RackDimensionUnitChoices.as_enum(prefix='unit'))
RackFormFactorEnum = strawberry.enum(RackFormFactorChoices.as_enum(prefix='type'))
RackStatusEnum = strawberry.enum(RackStatusChoices.as_enum(prefix='status'))
RackWidthEnum = strawberry.enum(RackWidthChoices.as_enum(prefix='width'))
SiteStatusEnum = strawberry.enum(SiteStatusChoices.as_enum(prefix='status'))
SubdeviceRoleEnum = strawberry.enum(SubdeviceRoleChoices.as_enum(prefix='role'))
VirtualDeviceContextStatusEnum = strawberry.enum(VirtualDeviceContextStatusChoices.as_enum(prefix='status'))

View File

@ -16,11 +16,11 @@ __all__ = (
CustomFieldChoiceSetBaseEnum = strawberry.enum(CustomFieldChoiceSetBaseChoices.as_enum())
CustomFieldFilterLogicEnum = strawberry.enum(CustomFieldFilterLogicChoices.as_enum())
CustomFieldTypeEnum = strawberry.enum(CustomFieldTypeChoices.as_enum())
CustomFieldFilterLogicEnum = strawberry.enum(CustomFieldFilterLogicChoices.as_enum(prefix='filter'))
CustomFieldTypeEnum = strawberry.enum(CustomFieldTypeChoices.as_enum(prefix='type'))
CustomFieldUIEditableEnum = strawberry.enum(CustomFieldUIEditableChoices.as_enum())
CustomFieldUIVisibleEnum = strawberry.enum(CustomFieldUIVisibleChoices.as_enum())
CustomLinkButtonClassEnum = strawberry.enum(CustomLinkButtonClassChoices.as_enum())
EventRuleActionEnum = strawberry.enum(EventRuleActionChoices.as_enum())
JournalEntryKindEnum = strawberry.enum(JournalEntryKindChoices.as_enum())
JournalEntryKindEnum = strawberry.enum(JournalEntryKindChoices.as_enum(prefix='kind'))
WebhookHttpMethodEnum = strawberry.enum(WebhookHttpMethodChoices.as_enum())

View File

@ -15,13 +15,13 @@ __all__ = (
'VLANQinQRoleEnum',
)
FHRPGroupAuthTypeEnum = strawberry.enum(FHRPGroupAuthTypeChoices.as_enum())
FHRPGroupProtocolEnum = strawberry.enum(FHRPGroupProtocolChoices.as_enum())
IPAddressFamilyEnum = strawberry.enum(IPAddressFamilyChoices.as_enum())
IPAddressRoleEnum = strawberry.enum(IPAddressRoleChoices.as_enum())
IPAddressStatusEnum = strawberry.enum(IPAddressStatusChoices.as_enum())
IPRangeStatusEnum = strawberry.enum(IPRangeStatusChoices.as_enum())
PrefixStatusEnum = strawberry.enum(PrefixStatusChoices.as_enum())
ServiceProtocolEnum = strawberry.enum(ServiceProtocolChoices.as_enum())
VLANStatusEnum = strawberry.enum(VLANStatusChoices.as_enum())
VLANQinQRoleEnum = strawberry.enum(VLANQinQRoleChoices.as_enum())
FHRPGroupAuthTypeEnum = strawberry.enum(FHRPGroupAuthTypeChoices.as_enum(prefix='authentication'))
FHRPGroupProtocolEnum = strawberry.enum(FHRPGroupProtocolChoices.as_enum(prefix='protocol'))
IPAddressFamilyEnum = strawberry.enum(IPAddressFamilyChoices.as_enum(prefix='family'))
IPAddressRoleEnum = strawberry.enum(IPAddressRoleChoices.as_enum(prefix='role'))
IPAddressStatusEnum = strawberry.enum(IPAddressStatusChoices.as_enum(prefix='status'))
IPRangeStatusEnum = strawberry.enum(IPRangeStatusChoices.as_enum(prefix='status'))
PrefixStatusEnum = strawberry.enum(PrefixStatusChoices.as_enum(prefix='status'))
ServiceProtocolEnum = strawberry.enum(ServiceProtocolChoices.as_enum(prefix='role'))
VLANStatusEnum = strawberry.enum(VLANStatusChoices.as_enum(prefix='status'))
VLANQinQRoleEnum = strawberry.enum(VLANQinQRoleChoices.as_enum(prefix='role'))

View File

@ -8,6 +8,6 @@ __all__ = (
'WeightUnitEnum',
)
ColorEnum = strawberry.enum(ColorChoices.as_enum())
ColorEnum = strawberry.enum(ColorChoices.as_enum(prefix='color'))
DistanceUnitEnum = strawberry.enum(DistanceUnitChoices.as_enum())
WeightUnitEnum = strawberry.enum(WeightUnitChoices.as_enum())

View File

@ -6,4 +6,4 @@ __all__ = (
'ContactPriorityEnum',
)
ContactPriorityEnum = strawberry.enum(ContactPriorityChoices.as_enum())
ContactPriorityEnum = strawberry.enum(ContactPriorityChoices.as_enum(prefix='priority'))

View File

@ -3,6 +3,8 @@ import enum
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from utilities.string import enum_key
__all__ = (
'ChoiceSet',
'unpack_grouped_choices',
@ -68,20 +70,14 @@ class ChoiceSet(metaclass=ChoiceSetMeta):
return [c[0] for c in unpack_grouped_choices(cls._choices)]
@classmethod
def as_enum(cls, name=None):
def as_enum(cls, name=None, prefix=''):
"""
Return the ChoiceSet as an Enum. If no name is provided, "Choices" will be stripped from the class name (if
present) and "Enum" will be appended. For example, "CircuitStatusChoices" will become "CircuitStatusEnum".
"""
name = name or f"{cls.__name__.split('Choices')[0]}Enum"
data = {}
choices = cls.values()
for attr in dir(cls):
value = getattr(cls, attr)
if attr.isupper() and value in choices:
data[attr] = value
prefix = f'{prefix}_' if prefix else ''
data = {f'{prefix}{enum_key(v)}'.upper(): v for v in cls.values()}
return enum.Enum(name, data)

View File

@ -1,9 +1,20 @@
import re
__all__ = (
'enum_key',
'title',
'trailing_slash',
)
def enum_key(value):
"""
Convert the given value to a string suitable for use as an Enum key.
"""
value = str(value).upper()
return re.sub(r'[^_A-Z0-9]', '_', value)
def title(value):
"""
Improved implementation of str.title(); retains all existing uppercase letters.

View File

@ -7,5 +7,5 @@ __all__ = (
'VirtualMachineStatusEnum',
)
ClusterStatusEnum = strawberry.enum(ClusterStatusChoices.as_enum())
VirtualMachineStatusEnum = strawberry.enum(VirtualMachineStatusChoices.as_enum())
ClusterStatusEnum = strawberry.enum(ClusterStatusChoices.as_enum(prefix='status'))
VirtualMachineStatusEnum = strawberry.enum(VirtualMachineStatusChoices.as_enum(prefix='status'))

View File

@ -17,15 +17,15 @@ __all__ = (
'TunnelTerminationTypeEnum',
)
AuthenticationAlgorithmEnum = strawberry.enum(AuthenticationAlgorithmChoices.as_enum())
AuthenticationAlgorithmEnum = strawberry.enum(AuthenticationAlgorithmChoices.as_enum(prefix='auth'))
AuthenticationMethodEnum = strawberry.enum(AuthenticationMethodChoices.as_enum())
DHGroupEnum = strawberry.enum(DHGroupChoices.as_enum())
EncryptionAlgorithmEnum = strawberry.enum(EncryptionAlgorithmChoices.as_enum())
DHGroupEnum = strawberry.enum(DHGroupChoices.as_enum(prefix='group'))
EncryptionAlgorithmEnum = strawberry.enum(EncryptionAlgorithmChoices.as_enum(prefix='encryption'))
IKEModeEnum = strawberry.enum(IKEModeChoices.as_enum())
IKEVersionEnum = strawberry.enum(IKEVersionChoices.as_enum())
IKEVersionEnum = strawberry.enum(IKEVersionChoices.as_enum(prefix='version'))
IPSecModeEnum = strawberry.enum(IPSecModeChoices.as_enum())
L2VPNTypeEnum = strawberry.enum(L2VPNTypeChoices.as_enum())
TunnelEncapsulationEnum = strawberry.enum(TunnelEncapsulationChoices.as_enum())
TunnelStatusEnum = strawberry.enum(TunnelStatusChoices.as_enum())
TunnelTerminationRoleEnum = strawberry.enum(TunnelTerminationRoleChoices.as_enum())
TunnelTerminationTypeEnum = strawberry.enum(TunnelTerminationTypeChoices.as_enum())
L2VPNTypeEnum = strawberry.enum(L2VPNTypeChoices.as_enum(prefix='type'))
TunnelEncapsulationEnum = strawberry.enum(TunnelEncapsulationChoices.as_enum(prefix='encap'))
TunnelStatusEnum = strawberry.enum(TunnelStatusChoices.as_enum(prefix='status'))
TunnelTerminationRoleEnum = strawberry.enum(TunnelTerminationRoleChoices.as_enum(prefix='role'))
TunnelTerminationTypeEnum = strawberry.enum(TunnelTerminationTypeChoices.as_enum(prefix='type'))

View File

@ -10,8 +10,8 @@ __all__ = (
'WirelessRoleEnum',
)
WirelessAuthCipherEnum = strawberry.enum(WirelessAuthCipherChoices.as_enum())
WirelessAuthTypeEnum = strawberry.enum(WirelessAuthTypeChoices.as_enum())
WirelessChannelEnum = strawberry.enum(WirelessChannelChoices.as_enum())
WirelessLANStatusEnum = strawberry.enum(WirelessLANStatusChoices.as_enum())
WirelessRoleEnum = strawberry.enum(WirelessRoleChoices.as_enum())
WirelessAuthCipherEnum = strawberry.enum(WirelessAuthCipherChoices.as_enum(prefix='cipher'))
WirelessAuthTypeEnum = strawberry.enum(WirelessAuthTypeChoices.as_enum(prefix='type'))
WirelessChannelEnum = strawberry.enum(WirelessChannelChoices.as_enum(prefix='channel'))
WirelessLANStatusEnum = strawberry.enum(WirelessLANStatusChoices.as_enum(prefix='status'))
WirelessRoleEnum = strawberry.enum(WirelessRoleChoices.as_enum(prefix='role'))