11from functools import partial
22from inspect import isclass
33
4- from graphql_relay import from_global_id , to_global_id
5-
6- from ..types import ID , Field , Interface , ObjectType
4+ from ..types import Field , Interface , ObjectType
75from ..types .interface import InterfaceOptions
86from ..types .utils import get_type
7+ from .id_type import BaseGlobalIDType , DefaultGlobalIDType
98
109
1110def is_node (objecttype ):
@@ -22,8 +21,18 @@ def is_node(objecttype):
2221
2322
2423class GlobalID (Field ):
25- def __init__ (self , node = None , parent_type = None , required = True , * args , ** kwargs ):
26- super (GlobalID , self ).__init__ (ID , required = required , * args , ** kwargs )
24+ def __init__ (
25+ self ,
26+ node = None ,
27+ parent_type = None ,
28+ required = True ,
29+ global_id_type = DefaultGlobalIDType ,
30+ * args ,
31+ ** kwargs ,
32+ ):
33+ super (GlobalID , self ).__init__ (
34+ global_id_type .graphene_type , required = required , * args , ** kwargs
35+ )
2736 self .node = node or Node
2837 self .parent_type_name = parent_type ._meta .name if parent_type else None
2938
@@ -47,12 +56,14 @@ def __init__(self, node, type_=False, **kwargs):
4756 assert issubclass (node , Node ), "NodeField can only operate in Nodes"
4857 self .node_type = node
4958 self .field_type = type_
59+ global_id_type = node ._meta .global_id_type
5060
5161 super (NodeField , self ).__init__ (
52- # If we don's specify a type, the field type will be the node
53- # interface
62+ # If we don't specify a type, the field type will be the node interface
5463 type_ or node ,
55- id = ID (required = True , description = "The ID of the object" ),
64+ id = global_id_type .graphene_type (
65+ required = True , description = "The ID of the object"
66+ ),
5667 ** kwargs ,
5768 )
5869
@@ -65,11 +76,23 @@ class Meta:
6576 abstract = True
6677
6778 @classmethod
68- def __init_subclass_with_meta__ (cls , ** options ):
79+ def __init_subclass_with_meta__ (cls , global_id_type = DefaultGlobalIDType , ** options ):
80+ assert issubclass (
81+ global_id_type , BaseGlobalIDType
82+ ), "Custom ID type need to be implemented as a subclass of BaseGlobalIDType."
6983 _meta = InterfaceOptions (cls )
70- _meta .fields = {"id" : GlobalID (cls , description = "The ID of the object" )}
84+ _meta .global_id_type = global_id_type
85+ _meta .fields = {
86+ "id" : GlobalID (
87+ cls , global_id_type = global_id_type , description = "The ID of the object"
88+ )
89+ }
7190 super (AbstractNode , cls ).__init_subclass_with_meta__ (_meta = _meta , ** options )
7291
92+ @classmethod
93+ def resolve_global_id (cls , info , global_id ):
94+ return cls ._meta .global_id_type .resolve_global_id (info , global_id )
95+
7396
7497class Node (AbstractNode ):
7598 """An object with an ID"""
@@ -84,16 +107,7 @@ def node_resolver(cls, only_type, root, info, id):
84107
85108 @classmethod
86109 def get_node_from_global_id (cls , info , global_id , only_type = None ):
87- try :
88- _type , _id = cls .from_global_id (global_id )
89- if not _type :
90- raise ValueError ("Invalid Global ID" )
91- except Exception as e :
92- raise Exception (
93- f'Unable to parse global ID "{ global_id } ". '
94- 'Make sure it is a base64 encoded string in the format: "TypeName:id". '
95- f"Exception message: { e } "
96- )
110+ _type , _id = cls .resolve_global_id (info , global_id )
97111
98112 graphene_type = info .schema .get_type (_type )
99113 if graphene_type is None :
@@ -116,10 +130,6 @@ def get_node_from_global_id(cls, info, global_id, only_type=None):
116130 if get_node :
117131 return get_node (info , _id )
118132
119- @classmethod
120- def from_global_id (cls , global_id ):
121- return from_global_id (global_id )
122-
123133 @classmethod
124134 def to_global_id (cls , type_ , id ):
125- return to_global_id (type_ , id )
135+ return cls . _meta . global_id_type . to_global_id (type_ , id )
0 commit comments