diff --git a/Makefile b/Makefile index 334a0c97..529ff45e 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,12 @@ clean: @rm -f .coverage 2> /dev/null @rm -rf .eggs 2> /dev/null @rm -rf .cache 2> /dev/null + @rm -rf ./graphene_mongo/.cache 2> /dev/null @rm -rf build 2> /dev/null @rm -rf dist 2> /dev/null @rm -rf graphene_mongo.egg-info 2> /dev/null @find . -name "*.pyc" -delete + @find . -name "*.swp" -delete @find . -name "__pycache__" -delete lint: diff --git a/graphene_mongo/fields.py b/graphene_mongo/fields.py index 1a37d14d..e54d15eb 100644 --- a/graphene_mongo/fields.py +++ b/graphene_mongo/fields.py @@ -65,8 +65,11 @@ def args(self, args): @property def default_filter_args(self): + def is_filterable(kv): + return hasattr(kv[1], '_type') and hasattr(kv[1]._type, '_of_type') + return reduce( - lambda r, kv: r.update({kv[0]: kv[1]._type._of_type()}) or r if hasattr(kv[1], '_type') else r, + lambda r, kv: r.update({kv[0]: kv[1]._type._of_type()}) or r if is_filterable(kv) else r, self.fields.items(), {} ) diff --git a/graphene_mongo/tests/models.py b/graphene_mongo/tests/models.py index 24cad3b1..225bb112 100644 --- a/graphene_mongo/tests/models.py +++ b/graphene_mongo/tests/models.py @@ -61,4 +61,4 @@ class Player(Document): last_name = StringField(required=True) opponent = ReferenceField('Player') players = ListField(ReferenceField('Player')) - articles = ListField(ReferenceField('Article')) + # articles = ListField(ReferenceField('Article')) diff --git a/graphene_mongo/tests/test_converter.py b/graphene_mongo/tests/test_converter.py index 421c5828..adcb96c2 100644 --- a/graphene_mongo/tests/test_converter.py +++ b/graphene_mongo/tests/test_converter.py @@ -10,6 +10,7 @@ from .models import Article, Editor, EmbeddedArticle, Player, Reporter from ..converter import convert_mongoengine_field +from ..fields import MongoengineConnectionField from ..types import MongoengineObjectType @@ -101,9 +102,8 @@ class Meta: dynamic_field = graphene_field.get_type() assert dynamic_field._of_type == A - def test_should_self_reference_convert_dynamic(): - + # pass class P(MongoengineObjectType): class Meta: @@ -116,6 +116,9 @@ class Meta: assert isinstance(graphene_type, graphene.Field) assert graphene_type.type == P + graphene_field = convert_mongoengine_field(Player._fields['players'], P._meta.registry) + assert isinstance(graphene_field, MongoengineConnectionField) + def test_should_list_of_self_reference_convert_list(): @@ -133,4 +136,3 @@ class Meta: assert isinstance(graphene_field, graphene.List) dynamic_field = graphene_field.get_type() assert dynamic_field._of_type == P - diff --git a/graphene_mongo/tests/test_query.py b/graphene_mongo/tests/test_query.py index 49dca518..bdf7f206 100644 --- a/graphene_mongo/tests/test_query.py +++ b/graphene_mongo/tests/test_query.py @@ -34,6 +34,8 @@ def setup_fixtures(): player1.save() player2 = Player(first_name='Magic', last_name='Johnson', opponent=player1) player2.save() + player3 = Player(first_name='Larry', last_name='Bird', players=[player1, player2]) + player3.save() setup_fixtures() @@ -403,50 +405,56 @@ def test_should_self_reference(): class Query(graphene.ObjectType): - players = MongoengineConnectionField(PlayerNode) + all_players = graphene.List(PlayerType) + + def resolve_all_players(self, *args, **kwargs): + return Player.objects.all() query = ''' - query PlayerQuery { - players { - edges { - cursor, - node { - firstName, - opponent { - firstName - } - } + query PlayersQuery { + allPlayers { + firstName, + opponent { + firstName + }, + players { + firstName } } } ''' expected = { - 'players': { - 'edges': [ - { - 'cursor': 'xxx', - 'node': { - 'firstName': 'Michael', - 'opponent': None - } + 'allPlayers': [ + { + 'firstName': 'Michael', + 'opponent': None, + 'players': [] + }, + { + 'firstName': 'Magic', + 'opponent': { + 'firstName': 'Michael' }, - { - 'cursor': 'xxx', - 'node': { - 'firstName': 'Magic', - 'opponent': { - 'firstName': 'Michael' - } + 'players': [] + }, + { + 'firstName': 'Larry', + 'opponent': None, + 'players': [ + { + 'firstName': 'Michael' + }, + { + 'firstName': 'Magic' } - } - ] - } + ] + } + ] } schema = graphene.Schema(query=Query) result = schema.execute(query) - assert not result.errors - assert all(item in get_nodes(result.data, 'players') for item in get_nodes(expected, 'players')) + assert json.dumps(result.data, sort_keys=True) == json.dumps(expected, sort_keys=True) # TODO: diff --git a/graphene_mongo/types.py b/graphene_mongo/types.py index d72b9dc0..fcae3d86 100644 --- a/graphene_mongo/types.py +++ b/graphene_mongo/types.py @@ -26,13 +26,15 @@ def construct_fields(model, registry, only_fields, exclude_fields): # Take care of list of self-reference. document_type_obj = field.field.__dict__.get('document_type_obj', None) if document_type_obj == model._class_name \ - or isinstance(document_type_obj, model): + or isinstance(document_type_obj, model) \ + or document_type_obj == model: self_referenced[name] = field continue converted = convert_mongoengine_field(field, registry) if not converted: continue fields[name] = converted + return fields, self_referenced