Skip to content

Commit a1de06c

Browse files
authored
Merge pull request #66 from heron182/feat/support-multipolygon-field
Add support for MultiPolygonField
2 parents 0b29a83 + 3f7e2fb commit a1de06c

File tree

8 files changed

+108
-11
lines changed

8 files changed

+108
-11
lines changed

graphene_mongo/advanced_types.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,33 @@
22

33

44
__all__ = [
5-
'PointFieldType'
5+
'PointFieldType',
6+
'MultiPolygonFieldType'
67
]
78

89

9-
def _resolve_point_type_coordinates(self, info):
10+
def _resolve_type_coordinates(self, info):
1011
return self['coordinates']
1112

1213

1314
class PointFieldType(graphene.ObjectType):
1415

1516
type = graphene.String()
1617
coordinates = graphene.List(
17-
graphene.Float, resolver=_resolve_point_type_coordinates)
18+
graphene.Float, resolver=_resolve_type_coordinates)
19+
20+
def resolve_type(self, info):
21+
return self['type']
22+
23+
24+
class MultiPolygonFieldType(graphene.ObjectType):
25+
26+
type = graphene.String()
27+
coordinates = graphene.List(
28+
graphene.List(
29+
graphene.List(
30+
graphene.List(graphene.Float))),
31+
resolver=_resolve_type_coordinates)
1832

1933
def resolve_type(self, info):
2034
return self['type']

graphene_mongo/converter.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import mongoengine
1717

18-
from .advanced_types import PointFieldType
18+
from .advanced_types import PointFieldType, MultiPolygonFieldType
1919
from .fields import MongoengineConnectionField
2020
from .utils import import_single_dispatch
2121

@@ -70,6 +70,11 @@ def convert_point_to_field(field, register=None):
7070
return Field(PointFieldType)
7171

7272

73+
@convert_mongoengine_field.register(mongoengine.MultiPolygonField)
74+
def convert_multipolygon_to_field(field, register=None):
75+
return Field(MultiPolygonFieldType)
76+
77+
7378
@convert_mongoengine_field.register(mongoengine.DateTimeField)
7479
def convert_field_to_datetime(field, registry=None):
7580
return DateTime(description=field.db_field, required=field.required)

graphene_mongo/fields.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from graphene.types.dynamic import Dynamic
1313
from graphene.types.structures import Structure
1414

15-
from .advanced_types import PointFieldType
15+
from .advanced_types import PointFieldType, MultiPolygonFieldType
1616
from .utils import get_model_reference_fields
1717

1818

@@ -60,7 +60,7 @@ def is_filterable(v):
6060
return False
6161
# FIXME: Skip PointTypeField at this moment.
6262
if not isinstance(v.type, Structure) \
63-
and isinstance(v.type(), PointFieldType):
63+
and isinstance(v.type(), (PointFieldType, MultiPolygonFieldType)):
6464
return False
6565
return True
6666

graphene_mongo/tests/models.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from mongoengine.fields import (
66
DateTimeField, EmailField, EmbeddedDocumentField,
77
FloatField, EmbeddedDocumentListField, ListField,
8-
MapField, PointField, ReferenceField, StringField
8+
MapField, PointField, ReferenceField, StringField,
9+
MultiPolygonField
910
)
1011

1112
connect('graphene-mongo-test', host='mongomock://localhost', alias='default')
@@ -69,6 +70,16 @@ class Parent(Document):
6970
'allow_inheritance': True
7071
}
7172
bar = StringField()
73+
loc = MultiPolygonField()
74+
75+
76+
class CellTower(Document):
77+
78+
meta = {
79+
'collection': 'test_cell_tower',
80+
}
81+
code = StringField()
82+
coverage_area = MultiPolygonField()
7283

7384

7485
class Child(Parent):

graphene_mongo/tests/setup.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
Article, Editor, EmbeddedArticle, Player,
66
Reporter, Child, ProfessorMetadata, ProfessorVector,
77
ChildRegisteredBefore, ChildRegisteredAfter,
8-
ParentWithRelationship,
8+
ParentWithRelationship, CellTower
99
)
1010

1111

@@ -98,6 +98,15 @@ def fixtures():
9898
child2 = Child(bar='bar', baz='baz', loc=[10, 20])
9999
child2.save()
100100

101+
CellTower.drop_collection()
102+
ct = CellTower(code='bar', coverage_area=[[[
103+
[-43.36556, -22.99669],
104+
[-43.36539, -23.01928],
105+
[-43.26583, -23.01802],
106+
[-43.36717, -22.98855],
107+
[-43.36636, -22.99351],
108+
[-43.36556, -22.99669]]]])
109+
ct.save()
101110
ProfessorVector.drop_collection()
102111
professor_metadata = ProfessorMetadata(
103112
id='5e06aa20-6805-4eef-a144-5615dedbe32b',

graphene_mongo/tests/test_converter.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ def test_should_point_convert_field():
9090
assert isinstance(graphene_type.type.coordinates, graphene.List)
9191

9292

93+
def test_should_multipolygon_convert_field():
94+
graphene_type = convert_mongoengine_field(mongoengine.MultiPolygonField())
95+
assert isinstance(graphene_type, graphene.Field)
96+
assert isinstance(graphene_type.type.type, graphene.String)
97+
assert isinstance(graphene_type.type.coordinates, graphene.List)
98+
99+
93100
def test_should_field_convert_list():
94101
assert_conversion(mongoengine.ListField, graphene.List, field=mongoengine.StringField())
95102

graphene_mongo/tests/test_query.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
from .setup import fixtures
66
from .models import (
7-
Child, Editor, Player, Reporter, ProfessorVector
7+
Child, Editor, Player, Reporter, ProfessorVector, Parent, CellTower
88
)
99
from .types import (
10-
ChildType, EditorType, PlayerType, ReporterType, ProfessorVectorType
10+
ChildType, EditorType, PlayerType, ReporterType, ProfessorVectorType, ParentType, CellTowerType
1111
)
1212

1313

@@ -310,3 +310,48 @@ def resolve_children(self, *args, **kwargs):
310310
assert not result.errors
311311
assert json.dumps(result.data, sort_keys=True) == \
312312
json.dumps(expected, sort_keys=True)
313+
314+
315+
def test_should_query_cell_tower(fixtures):
316+
317+
class Query(graphene.ObjectType):
318+
319+
cell_towers = graphene.List(CellTowerType)
320+
321+
def resolve_cell_towers(self, *args, **kwargs):
322+
return list(CellTower.objects.all())
323+
324+
query = '''
325+
query Query {
326+
cellTowers {
327+
code,
328+
coverageArea {
329+
type,
330+
coordinates
331+
}
332+
}
333+
}
334+
'''
335+
expected = {
336+
'cellTowers': [
337+
{
338+
'code': 'bar',
339+
'coverageArea': {
340+
'type': 'MultiPolygon',
341+
'coordinates': [[[
342+
[-43.36556, -22.99669],
343+
[-43.36539, -23.01928],
344+
[-43.26583, -23.01802],
345+
[-43.36717, -22.98855],
346+
[-43.36636, -22.99351],
347+
[-43.36556, -22.99669]]]]
348+
}
349+
}
350+
]
351+
}
352+
353+
schema = graphene.Schema(query=Query)
354+
result = schema.execute(query)
355+
assert not result.errors
356+
assert json.dumps(result.data, sort_keys=True) == \
357+
json.dumps(expected, sort_keys=True)

graphene_mongo/tests/types.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
Article, Editor, EmbeddedArticle, Player, Reporter,
66
Parent, Child, ProfessorMetadata, ProfessorVector,
77
ParentWithRelationship, ChildRegisteredBefore,
8-
ChildRegisteredAfter
8+
ChildRegisteredAfter, CellTower
99
)
1010

1111

@@ -51,6 +51,12 @@ class Meta:
5151
model = Child
5252

5353

54+
class CellTowerType(MongoengineObjectType):
55+
56+
class Meta:
57+
model = CellTower
58+
59+
5460
class ProfessorMetadataType(MongoengineObjectType):
5561

5662
class Meta:

0 commit comments

Comments
 (0)