Skip to content

Commit a4bc542

Browse files
committed
Added basic custom query filters
1 parent 3617415 commit a4bc542

File tree

5 files changed

+66
-15
lines changed

5 files changed

+66
-15
lines changed

graphene_mongo/fields.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def registry(self):
5959
def args(self):
6060
return to_arguments(
6161
self._base_args or OrderedDict(),
62-
dict(self.field_args, **self.reference_args)
62+
dict(dict(self.field_args, **self.reference_args), **self.filter_args)
6363
)
6464

6565
@args.setter
@@ -86,10 +86,9 @@ def is_filterable(k):
8686
return False
8787
if isinstance(converted, (ConnectionField, Dynamic)):
8888
return False
89-
if callable(getattr(converted, 'type', None)) \
90-
and isinstance(
91-
converted.type(),
92-
(FileFieldType, PointFieldType, MultiPolygonFieldType, graphene.Union)):
89+
if callable(getattr(converted, 'type', None)) and isinstance(converted.type(),
90+
(FileFieldType, PointFieldType,
91+
MultiPolygonFieldType, graphene.Union)):
9392
return False
9493
return True
9594

@@ -104,6 +103,17 @@ def get_type(v):
104103
def field_args(self):
105104
return self._field_args(self.fields.items())
106105

106+
@property
107+
def filter_args(self):
108+
filter_args = dict()
109+
if self._type._meta.filter_fields:
110+
for field, filter_collection in self._type._meta.filter_fields.items():
111+
for each in filter_collection:
112+
filter_args[field + "__" + each] = graphene.Argument(
113+
type=getattr(graphene, str(self._type._meta.fields[field].type).replace("!", "")))
114+
115+
return filter_args
116+
107117
@property
108118
def reference_args(self):
109119

@@ -178,12 +188,10 @@ def default_resolver(self, _root, info, **args):
178188
connection.list_length = list_length
179189
return connection
180190

181-
def chained_resolver(self, resolver, is_partial, root, info, **args):
182-
if not bool(args) or not is_partial:
183-
# XXX: Filter nested args
184-
resolved = resolver(root, info, **args)
185-
if resolved is not None:
186-
return resolved
191+
def chained_resolver(self, resolver, root, info, **args):
192+
resolved = resolver(root, info, **args)
193+
if resolved is not None:
194+
return resolved
187195
return self.default_resolver(root, info, **args)
188196

189197
@classmethod
@@ -201,5 +209,5 @@ def connection_resolver(cls, resolver, connection_type, root, info, **args):
201209
def get_resolver(self, parent_resolver):
202210
super_resolver = self.resolver or parent_resolver
203211
resolver = partial(
204-
self.chained_resolver, super_resolver, isinstance(super_resolver, partial))
212+
self.chained_resolver, super_resolver)
205213
return partial(self.connection_resolver, resolver, self.type)

graphene_mongo/tests/nodes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class PlayerNode(MongoengineObjectType):
4242
class Meta:
4343
model = models.Player
4444
interfaces = (Node, )
45+
filter_fields = {
46+
'first_name': ['istartswith']}
4547

4648

4749
class ReporterNode(MongoengineObjectType):

graphene_mongo/tests/test_converter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,4 @@ class Meta:
330330
Reporter._fields['generic_reference'], registry.get_global_registry())
331331
assert isinstance(generic_reference_field, graphene.Field)
332332
assert isinstance(generic_reference_field.type(), graphene.Union)
333+
assert generic_reference_field.type()._meta.types == (A, E)

graphene_mongo/tests/test_relay_query.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import base64
21
import os
2+
import json
33
import pytest
4-
4+
import base64
55
import graphene
66

77
from graphene.relay import Node
@@ -1038,3 +1038,43 @@ class Query(graphene.ObjectType):
10381038
result = schema.execute(query)
10391039
assert not result.errors
10401040
assert result.data == expected
1041+
1042+
1043+
def test_should_filter_mongoengine_queryset(fixtures):
1044+
1045+
class Query(graphene.ObjectType):
1046+
players = MongoengineConnectionField(nodes.PlayerNode)
1047+
1048+
query = '''
1049+
query players {
1050+
players(firstName_Istartswith: "M") {
1051+
edges {
1052+
node {
1053+
firstName
1054+
}
1055+
}
1056+
}
1057+
}
1058+
'''
1059+
expected = {
1060+
'players': {
1061+
'edges': [
1062+
{
1063+
'node': {
1064+
'firstName': 'Michael',
1065+
}
1066+
},
1067+
{
1068+
'node': {
1069+
'firstName': 'Magic'
1070+
}
1071+
}
1072+
]
1073+
}
1074+
}
1075+
schema = graphene.Schema(query=Query)
1076+
result = schema.execute(query)
1077+
1078+
assert not result.errors
1079+
assert json.dumps(result.data, sort_keys=True) == json.dumps(expected, sort_keys=True)
1080+

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ iso8601==0.1.12
77
mongoengine==0.16.3
88
mongomock==3.14.0
99
pymongo==3.6.1
10-
pytest==3.3.2
10+
pytest==5.0.1
1111
pytest-cov==2.5.1
1212
singledispatch==3.4.0.3

0 commit comments

Comments
 (0)