9478 link peers to GraphQL (#10574)

* 9468 add link_peer to GraphQL

* 9478 add class_type

* 9478 fix tests

* 9478 fix tests

* 9478 fix tests
This commit is contained in:
Arthur Hanson 2022-10-06 13:50:53 -07:00 committed by GitHub
parent 664d5db5eb
commit 10bb8fa10a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 6 deletions

View File

@ -0,0 +1,59 @@
import graphene
from circuits.graphql.types import CircuitTerminationType
from circuits.models import CircuitTermination
from dcim.graphql.types import (
ConsolePortType,
ConsoleServerPortType,
FrontPortType,
InterfaceType,
PowerFeedType,
PowerOutletType,
PowerPortType,
RearPortType,
)
from dcim.models import (
ConsolePort,
ConsoleServerPort,
FrontPort,
Interface,
PowerFeed,
PowerOutlet,
PowerPort,
RearPort,
)
class LinkPeerType(graphene.Union):
class Meta:
types = (
CircuitTerminationType,
ConsolePortType,
ConsoleServerPortType,
FrontPortType,
InterfaceType,
PowerFeedType,
PowerOutletType,
PowerPortType,
RearPortType,
)
@classmethod
def resolve_type(cls, instance, info):
if type(instance) == CircuitTermination:
return CircuitTerminationType
if type(instance) == ConsolePortType:
return ConsolePortType
if type(instance) == ConsoleServerPort:
return ConsoleServerPortType
if type(instance) == FrontPort:
return FrontPortType
if type(instance) == Interface:
return InterfaceType
if type(instance) == PowerFeed:
return PowerFeedType
if type(instance) == PowerOutlet:
return PowerOutletType
if type(instance) == PowerPort:
return PowerPortType
if type(instance) == RearPort:
return RearPortType

View File

@ -1,5 +1,12 @@
import graphene
class CabledObjectMixin: class CabledObjectMixin:
link_peers = graphene.List('dcim.graphql.gfk_mixins.LinkPeerType')
def resolve_cable_end(self, info): def resolve_cable_end(self, info):
# Handle empty values # Handle empty values
return self.cable_end or None return self.cable_end or None
def resolve_link_peers(self, info):
return self.link_peers

View File

@ -1,10 +1,14 @@
import graphene import graphene
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from extras.graphql.mixins import (
ChangelogMixin,
CustomFieldsMixin,
JournalEntriesMixin,
TagsMixin,
)
from graphene_django import DjangoObjectType from graphene_django import DjangoObjectType
from extras.graphql.mixins import ChangelogMixin, CustomFieldsMixin, JournalEntriesMixin, TagsMixin
__all__ = ( __all__ = (
'BaseObjectType', 'BaseObjectType',
'ObjectType', 'ObjectType',
@ -22,9 +26,7 @@ class BaseObjectType(DjangoObjectType):
Base GraphQL object type for all NetBox objects. Restricts the model queryset to enforce object permissions. Base GraphQL object type for all NetBox objects. Restricts the model queryset to enforce object permissions.
""" """
display = graphene.String() display = graphene.String()
class_type = graphene.String()
def resolve_display(parent, info, **kwargs):
return str(parent)
class Meta: class Meta:
abstract = True abstract = True
@ -34,6 +36,12 @@ class BaseObjectType(DjangoObjectType):
# Enforce object permissions on the queryset # Enforce object permissions on the queryset
return queryset.restrict(info.context.user, 'view') return queryset.restrict(info.context.user, 'view')
def resolve_display(parent, info, **kwargs):
return str(parent)
def resolve_class_type(parent, info, **kwargs):
return parent.__class__.__name__
class ObjectType( class ObjectType(
ChangelogMixin, ChangelogMixin,

View File

@ -1,3 +1,4 @@
import inspect
import json import json
from django.conf import settings from django.conf import settings
@ -5,7 +6,7 @@ from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.urls import reverse from django.urls import reverse
from django.test import override_settings from django.test import override_settings
from graphene.types import Dynamic as GQLDynamic, List as GQLList from graphene.types import Dynamic as GQLDynamic, List as GQLList, Union as GQLUnion
from rest_framework import status from rest_framework import status
from rest_framework.test import APIClient from rest_framework.test import APIClient
@ -449,6 +450,9 @@ class APIViewTestCases:
if type(field) is GQLDynamic: if type(field) is GQLDynamic:
# Dynamic fields must specify a subselection # Dynamic fields must specify a subselection
fields_string += f'{field_name} {{ id }}\n' fields_string += f'{field_name} {{ id }}\n'
elif type(field.type) is GQLList and inspect.isclass(field.type.of_type) and issubclass(field.type.of_type, GQLUnion):
# Union types dont' have an id or consistent values
continue
elif type(field.type) is GQLList and field_name != 'choices': elif type(field.type) is GQLList and field_name != 'choices':
# TODO: Come up with something more elegant # TODO: Come up with something more elegant
# Temporary hack to support automated testing of reverse generic relations # Temporary hack to support automated testing of reverse generic relations