1- from graphene import (ID , Boolean , Dynamic , Field , Float , Int , List ,
2- NonNull , String , is_node )
3- from graphene .types .json import JSONString
4-
51import mongoengine
2+ import uuid
3+ from graphene import (
4+ ID ,
5+ Boolean ,
6+ DateTime ,
7+ Dynamic ,
8+ Field ,
9+ Float ,
10+ Int ,
11+ List ,
12+ NonNull ,
13+ String ,
14+ Union ,
15+ is_node
16+ )
17+ from graphene .types .json import JSONString
18+ from mongoengine .base import get_document
619
7- from .fields import MongoengineConnectionField
8- from .utils import import_single_dispatch
20+ from . import advanced_types
21+ from .utils import (
22+ import_single_dispatch , get_field_description ,
23+ )
924
1025singledispatch = import_single_dispatch ()
1126
1227
28+ class MongoEngineConversionError (Exception ):
29+ pass
30+
31+
1332@singledispatch
1433def convert_mongoengine_field (field , registry = None ):
15- raise Exception (
34+ raise MongoEngineConversionError (
1635 "Don't know how to convert the MongoEngine field %s (%s)" %
1736 (field , field .__class__ ))
1837
@@ -21,41 +40,61 @@ def convert_mongoengine_field(field, registry=None):
2140@convert_mongoengine_field .register (mongoengine .StringField )
2241@convert_mongoengine_field .register (mongoengine .URLField )
2342def convert_field_to_string (field , registry = None ):
24- return String (description = field . db_field , required = field .required )
43+ return String (description = get_field_description ( field , registry ) , required = field .required )
2544
2645
2746@convert_mongoengine_field .register (mongoengine .UUIDField )
2847@convert_mongoengine_field .register (mongoengine .ObjectIdField )
2948def convert_field_to_id (field , registry = None ):
30- return ID (description = field . db_field , required = field .required )
49+ return ID (description = get_field_description ( field , registry ) , required = field .required )
3150
3251
3352@convert_mongoengine_field .register (mongoengine .IntField )
3453@convert_mongoengine_field .register (mongoengine .LongField )
3554def convert_field_to_int (field , registry = None ):
36- return Int (description = field . db_field , required = field .required )
55+ return Int (description = get_field_description ( field , registry ) , required = field .required )
3756
3857
3958@convert_mongoengine_field .register (mongoengine .BooleanField )
4059def convert_field_to_boolean (field , registry = None ):
41- return Boolean (description = field . db_field , required = field .required )
60+ return Boolean (description = get_field_description ( field , registry ) , required = field .required )
4261
4362
4463@convert_mongoengine_field .register (mongoengine .DecimalField )
4564@convert_mongoengine_field .register (mongoengine .FloatField )
4665def convert_field_to_float (field , registry = None ):
47- return Float (description = field .db_field , required = field .required )
66+ return Float (description = get_field_description (field , registry ), required = field .required )
67+
68+
69+ @convert_mongoengine_field .register (mongoengine .DateTimeField )
70+ def convert_field_to_datetime (field , registry = None ):
71+ return DateTime (description = get_field_description (field , registry ), required = field .required )
4872
4973
5074@convert_mongoengine_field .register (mongoengine .DictField )
5175@convert_mongoengine_field .register (mongoengine .MapField )
52- def convert_dict_to_jsonstring (field , registry = None ):
53- return JSONString (description = field . db_field , required = field .required )
76+ def convert_field_to_jsonstring (field , registry = None ):
77+ return JSONString (description = get_field_description ( field , registry ) , required = field .required )
5478
5579
56- @convert_mongoengine_field .register (mongoengine .DateTimeField )
57- def convert_date_to_string (field , registry = None ):
58- return String (description = field .db_field , required = field .required )
80+ @convert_mongoengine_field .register (mongoengine .PointField )
81+ def convert_point_to_field (field , registry = None ):
82+ return Field (advanced_types .PointFieldType )
83+
84+
85+ @convert_mongoengine_field .register (mongoengine .PolygonField )
86+ def convert_polygon_to_field (field , registry = None ):
87+ return Field (advanced_types .PolygonFieldType )
88+
89+
90+ @convert_mongoengine_field .register (mongoengine .MultiPolygonField )
91+ def convert_multipolygon_to_field (field , register = None ):
92+ return Field (advanced_types .MultiPolygonFieldType )
93+
94+
95+ @convert_mongoengine_field .register (mongoengine .FileField )
96+ def convert_file_to_field (field , registry = None ):
97+ return Field (advanced_types .FileFieldType )
5998
6099
61100@convert_mongoengine_field .register (mongoengine .ListField )
@@ -69,15 +108,43 @@ def convert_field_to_list(field, registry=None):
69108 base_type = base_type ._type
70109
71110 if is_node (base_type ):
72- return MongoengineConnectionField (base_type )
111+ return base_type . _meta . connection_field_class (base_type )
73112
74113 # Non-relationship field
75114 relations = (mongoengine .ReferenceField , mongoengine .EmbeddedDocumentField )
76115 if not isinstance (base_type , (List , NonNull )) \
77116 and not isinstance (field .field , relations ):
78117 base_type = type (base_type )
79118
80- return List (base_type , description = field .db_field , required = field .required )
119+ return List (base_type , description = get_field_description (field , registry ), required = field .required )
120+
121+
122+ @convert_mongoengine_field .register (mongoengine .GenericReferenceField )
123+ def convert_field_to_union (field , registry = None ):
124+
125+ _types = []
126+ for choice in field .choices :
127+ _field = mongoengine .ReferenceField (get_document (choice ))
128+ _field = convert_mongoengine_field (_field , registry )
129+ _type = _field .get_type ()
130+ if _type :
131+ _types .append (_type .type )
132+ else :
133+ # TODO: Register type auto-matically here.
134+ pass
135+
136+ if len (_types ) == 0 :
137+ return None
138+
139+ # XXX: Use uuid to avoid duplicate name
140+ name = '{}_{}_union_{}' .format (
141+ field ._owner_document .__name__ ,
142+ field .db_field ,
143+ str (uuid .uuid1 ()).replace ('-' , '' )
144+ )
145+ Meta = type ('Meta' , (object , ), {'types' : tuple (_types )})
146+ _union = type (name , (Union , ), {'Meta' : Meta })
147+ return Field (_union )
81148
82149
83150@convert_mongoengine_field .register (mongoengine .EmbeddedDocumentField )
@@ -89,6 +156,23 @@ def dynamic_type():
89156 _type = registry .get_type_for_model (model )
90157 if not _type :
91158 return None
92- return Field (_type )
159+ return Field (_type , description = get_field_description (field , registry ))
160+
161+ return Dynamic (dynamic_type )
162+
163+
164+ @convert_mongoengine_field .register (mongoengine .LazyReferenceField )
165+ def convert_lazy_field_to_dynamic (field , registry = None ):
166+ model = field .document_type
167+
168+ def lazy_resolver (root , * args , ** kwargs ):
169+ if getattr (root , field .name or field .db_name ):
170+ return getattr (root , field .name or field .db_name ).fetch ()
171+
172+ def dynamic_type ():
173+ _type = registry .get_type_for_model (model )
174+ if not _type :
175+ return None
176+ return Field (_type , resolver = lazy_resolver , description = get_field_description (field , registry ))
93177
94178 return Dynamic (dynamic_type )
0 commit comments