4
4
from graphene .relay import Connection , Node
5
5
from graphene .types .objecttype import ObjectType , ObjectTypeOptions
6
6
from graphene .types .utils import yank_fields_from_attrs
7
+ from mongoengine import ListField
7
8
8
9
from .converter import convert_mongoengine_field
9
10
from .registry import Registry , get_global_registry
13
14
def construct_fields (model , registry , only_fields , exclude_fields ):
14
15
_model_fields = get_model_fields (model )
15
16
fields = OrderedDict ()
17
+ self_referenced = OrderedDict ()
16
18
for name , field in _model_fields .items ():
17
19
is_not_in_only = only_fields and name not in only_fields
18
20
is_excluded = name in exclude_fields
19
21
if is_not_in_only or is_excluded :
20
22
# We skip this field if we specify only_fields and is not
21
23
# in there. Or when we exclude this field in exclude_fields
22
24
continue
25
+ if isinstance (field , ListField ):
26
+ # Take care of list of self-reference.
27
+ document_type_obj = field .field .__dict__ .get ('document_type_obj' , None )
28
+ if document_type_obj == model ._class_name \
29
+ or isinstance (document_type_obj , model ):
30
+ self_referenced [name ] = field
31
+ continue
32
+ converted = convert_mongoengine_field (field , registry )
33
+ if not converted :
34
+ continue
35
+ fields [name ] = converted
36
+ return fields , self_referenced
37
+
38
+
39
+ def construct_self_referenced_fields (self_referenced , registry ):
40
+ fields = OrderedDict ()
41
+ for name , field in self_referenced .items ():
23
42
converted = convert_mongoengine_field (field , registry )
24
43
if not converted :
25
44
continue
@@ -55,10 +74,11 @@ def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=Fa
55
74
'Registry, received "{}".'
56
75
).format (cls .__name__ , registry )
57
76
58
- mongoengine_fields = yank_fields_from_attrs (
59
- construct_fields (model , registry , only_fields , exclude_fields ),
60
- _as = Field
77
+ converted_fields , self_referenced = construct_fields (
78
+ model , registry , only_fields , exclude_fields
61
79
)
80
+ mongoengine_fields = yank_fields_from_attrs (converted_fields , _as = Field )
81
+
62
82
if use_connection is None and interfaces :
63
83
use_connection = any ((issubclass (interface , Node ) for interface in interfaces ))
64
84
@@ -81,12 +101,19 @@ def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=Fa
81
101
_meta .fields = mongoengine_fields
82
102
_meta .filter_fields = filter_fields
83
103
_meta .connection = connection
104
+
84
105
super (MongoengineObjectType , cls ).__init_subclass_with_meta__ (
85
106
_meta = _meta , interfaces = interfaces , ** options
86
107
)
87
108
88
109
if not skip_registry :
89
110
registry .register (cls )
111
+ # Notes: Take care list of self-reference fields.
112
+ converted_fields = construct_self_referenced_fields (self_referenced , registry )
113
+ if converted_fields :
114
+ mongoengine_fields = yank_fields_from_attrs (converted_fields , _as = Field )
115
+ cls ._meta .fields .update (mongoengine_fields )
116
+ registry .register (cls )
90
117
91
118
@classmethod
92
119
def is_type_of (cls , root , info ):
0 commit comments