1
1
from functools import partial
2
2
from inspect import isclass
3
3
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
7
5
from ..types .interface import InterfaceOptions
8
6
from ..types .utils import get_type
7
+ from .id_type import BaseGlobalIDType , DefaultGlobalIDType
9
8
10
9
11
10
def is_node (objecttype ):
@@ -22,8 +21,18 @@ def is_node(objecttype):
22
21
23
22
24
23
class 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
+ )
27
36
self .node = node or Node
28
37
self .parent_type_name = parent_type ._meta .name if parent_type else None
29
38
@@ -47,12 +56,14 @@ def __init__(self, node, type_=False, **kwargs):
47
56
assert issubclass (node , Node ), "NodeField can only operate in Nodes"
48
57
self .node_type = node
49
58
self .field_type = type_
59
+ global_id_type = node ._meta .global_id_type
50
60
51
61
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
54
63
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
+ ),
56
67
** kwargs ,
57
68
)
58
69
@@ -65,11 +76,23 @@ class Meta:
65
76
abstract = True
66
77
67
78
@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."
69
83
_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
+ }
71
90
super (AbstractNode , cls ).__init_subclass_with_meta__ (_meta = _meta , ** options )
72
91
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
+
73
96
74
97
class Node (AbstractNode ):
75
98
"""An object with an ID"""
@@ -84,16 +107,7 @@ def node_resolver(cls, only_type, root, info, id):
84
107
85
108
@classmethod
86
109
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 )
97
111
98
112
graphene_type = info .schema .get_type (_type )
99
113
if graphene_type is None :
@@ -116,10 +130,6 @@ def get_node_from_global_id(cls, info, global_id, only_type=None):
116
130
if get_node :
117
131
return get_node (info , _id )
118
132
119
- @classmethod
120
- def from_global_id (cls , global_id ):
121
- return from_global_id (global_id )
122
-
123
133
@classmethod
124
134
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