diff --git a/graphene_mongo/advanced_types.py b/graphene_mongo/advanced_types.py index 9ff3af03..9094d3d0 100644 --- a/graphene_mongo/advanced_types.py +++ b/graphene_mongo/advanced_types.py @@ -11,7 +11,7 @@ def _resolve_type_coordinates(self, info): return self['coordinates'] -class _CoordinatesField(graphene.ObjectType): +class _TypeField(graphene.ObjectType): type = graphene.String() @@ -19,13 +19,13 @@ def resolve_type(self, info): return self['type'] -class PointFieldType(_CoordinatesField): +class PointFieldType(_TypeField): coordinates = graphene.List( graphene.Float, resolver=_resolve_type_coordinates) -class PolygonFieldType(_CoordinatesField): +class PolygonFieldType(_TypeField): coordinates = graphene.List( graphene.List( @@ -34,7 +34,7 @@ class PolygonFieldType(_CoordinatesField): ) -class MultiPolygonFieldType(_CoordinatesField): +class MultiPolygonFieldType(_TypeField): coordinates = graphene.List( graphene.List( diff --git a/graphene_mongo/converter.py b/graphene_mongo/converter.py index 7e452951..a357ac71 100644 --- a/graphene_mongo/converter.py +++ b/graphene_mongo/converter.py @@ -1,3 +1,5 @@ +import mongoengine +import uuid from graphene import ( ID, Boolean, @@ -9,14 +11,16 @@ List, NonNull, String, + Union, is_node ) from graphene.types.json import JSONString - -import mongoengine +from mongoengine.base import get_document from . import advanced_types -from .utils import import_single_dispatch, get_field_description +from .utils import ( + import_single_dispatch, get_field_description, +) singledispatch = import_single_dispatch() @@ -110,6 +114,34 @@ def convert_field_to_list(field, registry=None): return List(base_type, description=get_field_description(field, registry), required=field.required) +@convert_mongoengine_field.register(mongoengine.GenericReferenceField) +def convert_field_to_union(field, registry=None): + + _types = [] + for choice in field.choices: + _field = mongoengine.ReferenceField(get_document(choice)) + _field = convert_mongoengine_field(_field, registry) + _type = _field.get_type() + if _type: + _types.append(_type.type) + else: + # TODO: Register type auto-matically here. + pass + + if len(_types) == 0: + return None + + # XXX: Use uuid to avoid duplicate name + name = '{}_{}_union_{}'.format( + field._owner_document.__name__, + field.db_field, + str(uuid.uuid1()).replace('-', '') + ) + Meta = type('Meta', (object, ), {'types': tuple(_types)}) + _union = type(name, (Union, ), {'Meta': Meta}) + return Field(_union) + + @convert_mongoengine_field.register(mongoengine.EmbeddedDocumentField) @convert_mongoengine_field.register(mongoengine.ReferenceField) def convert_field_to_dynamic(field, registry=None): diff --git a/graphene_mongo/fields.py b/graphene_mongo/fields.py index fab4f8ac..bd7121aa 100644 --- a/graphene_mongo/fields.py +++ b/graphene_mongo/fields.py @@ -3,8 +3,8 @@ from collections import OrderedDict from functools import partial, reduce +import graphene import mongoengine -from graphene import PageInfo from graphene.relay import ConnectionField from graphene.types.argument import to_arguments from graphene.types.dynamic import Dynamic @@ -65,6 +65,13 @@ def args(self, args): def _field_args(self, items): def is_filterable(k): + """ + Args: + k (str): field name. + Returns: + bool + """ + if not hasattr(self.model, k): return False if isinstance(getattr(self.model, k), property): @@ -75,8 +82,10 @@ def is_filterable(k): return False if isinstance(converted, (ConnectionField, Dynamic)): return False - if callable(getattr(converted, 'type', None)) and isinstance(converted.type(), - (PointFieldType, MultiPolygonFieldType)): + if callable(getattr(converted, 'type', None)) \ + and isinstance( + converted.type(), + (PointFieldType, MultiPolygonFieldType, graphene.Union)): return False return True @@ -158,7 +167,7 @@ def default_resolver(self, _root, info, **args): list_length=list_length, connection_type=self.type, edge_type=self.type.Edge, - pageinfo_type=PageInfo, + pageinfo_type=graphene.PageInfo, ) connection.iterable = objs connection.list_length = list_length diff --git a/graphene_mongo/tests/models.py b/graphene_mongo/tests/models.py index 3b1ee8e6..400a1e5d 100644 --- a/graphene_mongo/tests/models.py +++ b/graphene_mongo/tests/models.py @@ -1,21 +1,13 @@ +import mongoengine from datetime import datetime -from mongoengine import ( - connect, Document, EmbeddedDocument -) -from mongoengine.fields import ( - DateTimeField, EmailField, EmbeddedDocumentField, - FloatField, EmbeddedDocumentListField, ListField, LazyReferenceField, - MapField, MultiPolygonField, PointField, PolygonField, - ReferenceField, StringField, -) -connect('graphene-mongo-test', host='mongomock://localhost', alias='default') +mongoengine.connect('graphene-mongo-test', host='mongomock://localhost', alias='default') -class Publisher(Document): +class Publisher(mongoengine.Document): meta = {'collection': 'test_publisher'} - name = StringField() + name = mongoengine.StringField() @property def legal_name(self): @@ -25,129 +17,145 @@ def bad_field(self): return None -class Editor(Document): +class Editor(mongoengine.Document): """ An Editor of a publication. """ meta = {'collection': 'test_editor'} - id = StringField(primary_key=True) - first_name = StringField(required=True, help_text="Editor's first name.", db_field='fname') - last_name = StringField(required=True, help_text="Editor's last name.") - metadata = MapField(field=StringField(), help_text="Arbitrary metadata.") - company = LazyReferenceField(Publisher) + id = mongoengine.StringField(primary_key=True) + first_name = mongoengine.StringField(required=True, help_text="Editor's first name.", db_field='fname') + last_name = mongoengine.StringField(required=True, help_text="Editor's last name.") + metadata = mongoengine.MapField(field=mongoengine.StringField(), help_text="Arbitrary metadata.") + company = mongoengine.LazyReferenceField(Publisher) -class Article(Document): +class Article(mongoengine.Document): meta = {'collection': 'test_article'} - headline = StringField(required=True, help_text="The article headline.") - pub_date = DateTimeField(default=datetime.now, - verbose_name="publication date", - help_text="The date of first press.") - editor = ReferenceField(Editor) - reporter = ReferenceField('Reporter') + headline = mongoengine.StringField(required=True, help_text="The article headline.") + pub_date = mongoengine.DateTimeField( + default=datetime.now, + verbose_name="publication date", + help_text="The date of first press.") + editor = mongoengine.ReferenceField(Editor) + reporter = mongoengine.ReferenceField('Reporter') + # Will not convert this field cause no chioces + generic_reference = mongoengine.GenericReferenceField() -class EmbeddedArticle(EmbeddedDocument): +class EmbeddedArticle(mongoengine.EmbeddedDocument): meta = {'collection': 'test_embedded_article'} - headline = StringField(required=True) - pub_date = DateTimeField(default=datetime.now) - editor = ReferenceField(Editor) - reporter = ReferenceField('Reporter') + headline = mongoengine.StringField(required=True) + pub_date = mongoengine.DateTimeField(default=datetime.now) + editor = mongoengine.ReferenceField(Editor) + reporter = mongoengine.ReferenceField('Reporter') -class Reporter(Document): +class Reporter(mongoengine.Document): meta = {'collection': 'test_reporter'} - id = StringField(primary_key=True) - first_name = StringField(required=True) - last_name = StringField(required=True) - email = EmailField() - awards = ListField(StringField()) - articles = ListField(ReferenceField(Article)) - embedded_articles = ListField(EmbeddedDocumentField(EmbeddedArticle)) - embedded_list_articles = EmbeddedDocumentListField(EmbeddedArticle) - - -class Player(Document): + id = mongoengine.StringField(primary_key=True) + first_name = mongoengine.StringField(required=True) + last_name = mongoengine.StringField(required=True) + email = mongoengine.EmailField() + awards = mongoengine.ListField(mongoengine.StringField()) + articles = mongoengine.ListField(mongoengine.ReferenceField(Article)) + embedded_articles = mongoengine.ListField(mongoengine.EmbeddedDocumentField(EmbeddedArticle)) + embedded_list_articles = mongoengine.EmbeddedDocumentListField(EmbeddedArticle) + id = mongoengine.StringField(primary_key=True) + first_name = mongoengine.StringField(required=True) + last_name = mongoengine.StringField(required=True) + email = mongoengine.EmailField() + awards = mongoengine.ListField(mongoengine.StringField()) + articles = mongoengine.ListField(mongoengine.ReferenceField(Article)) + embedded_articles = mongoengine.ListField(mongoengine.EmbeddedDocumentField(EmbeddedArticle)) + embedded_list_articles = mongoengine.EmbeddedDocumentListField(EmbeddedArticle) + generic_reference = mongoengine.GenericReferenceField( + choices=[Article, Editor, ] + ) + + +class Player(mongoengine.Document): meta = {'collection': 'test_player'} - first_name = StringField(required=True) - last_name = StringField(required=True) - opponent = ReferenceField('Player') - players = ListField(ReferenceField('Player')) - articles = ListField(ReferenceField('Article')) - embedded_list_articles = EmbeddedDocumentListField(EmbeddedArticle) + first_name = mongoengine.StringField(required=True) + last_name = mongoengine.StringField(required=True) + opponent = mongoengine.ReferenceField('Player') + players = mongoengine.ListField(mongoengine.ReferenceField('Player')) + articles = mongoengine.ListField(mongoengine.ReferenceField('Article')) + embedded_list_articles = mongoengine.EmbeddedDocumentListField(EmbeddedArticle) -class Parent(Document): +class Parent(mongoengine.Document): meta = { 'collection': 'test_parent', 'allow_inheritance': True } - bar = StringField() - loc = MultiPolygonField() + bar = mongoengine.StringField() + loc = mongoengine.MultiPolygonField() -class CellTower(Document): +class CellTower(mongoengine.Document): meta = { 'collection': 'test_cell_tower', } - code = StringField() - base = PolygonField() - coverage_area = MultiPolygonField() + code = mongoengine.StringField() + base = mongoengine.PolygonField() + coverage_area = mongoengine.MultiPolygonField() class Child(Parent): meta = {'collection': 'test_child'} - baz = StringField() - loc = PointField() + baz = mongoengine.StringField() + loc = mongoengine.PointField() -class ProfessorMetadata(EmbeddedDocument): +class ProfessorMetadata(mongoengine.EmbeddedDocument): meta = {'collection': 'test_professor_metadata'} - id = StringField(primary_key=False) - first_name = StringField() - last_name = StringField() - departments = ListField(StringField()) + id = mongoengine.StringField(primary_key=False) + first_name = mongoengine.StringField() + last_name = mongoengine.StringField() + departments = mongoengine.ListField(mongoengine.StringField()) -class ProfessorVector(Document): +class ProfessorVector(mongoengine.Document): meta = {'collection': 'test_professor_vector'} - vec = ListField(FloatField()) - metadata = EmbeddedDocumentField(ProfessorMetadata) + vec = mongoengine.ListField(mongoengine.FloatField()) + metadata = mongoengine.EmbeddedDocumentField(ProfessorMetadata) -class ParentWithRelationship(Document): +class ParentWithRelationship(mongoengine.Document): meta = {'collection': 'test_parent_reference'} - before_child = ListField(ReferenceField("ChildRegisteredBefore")) - after_child = ListField(ReferenceField("ChildRegisteredAfter")) - name = StringField() + before_child = mongoengine.ListField( + mongoengine.ReferenceField('ChildRegisteredBefore')) + after_child = mongoengine.ListField( + mongoengine.ReferenceField('ChildRegisteredAfter')) + name = mongoengine.StringField() -class ChildRegisteredBefore(Document): +class ChildRegisteredBefore(mongoengine.Document): meta = {'collection': 'test_child_before_reference'} - parent = ReferenceField(ParentWithRelationship) - name = StringField() + parent = mongoengine.ReferenceField(ParentWithRelationship) + name = mongoengine.StringField() -class ChildRegisteredAfter(Document): +class ChildRegisteredAfter(mongoengine.Document): meta = {'collection': 'test_child_after_reference'} - parent = ReferenceField(ParentWithRelationship) - name = StringField() + parent = mongoengine.ReferenceField(ParentWithRelationship) + name = mongoengine.StringField() -class ErroneousModel(Document): +class ErroneousModel(mongoengine.Document): meta = {'collection': 'test_colliding_objects_model'} - objects = ListField(StringField()) + objects = mongoengine.ListField(mongoengine.StringField()) diff --git a/graphene_mongo/tests/nodes.py b/graphene_mongo/tests/nodes.py new file mode 100644 index 00000000..76eed2b6 --- /dev/null +++ b/graphene_mongo/tests/nodes.py @@ -0,0 +1,99 @@ +import graphene +from graphene.relay import Node + +from . import models +from . import types # noqa: F401 +from ..types import MongoengineObjectType + + +class PublisherNode(MongoengineObjectType): + legal_name = graphene.String() + bad_field = graphene.String() + + class Meta: + model = models.Publisher + only_fields = ('id', 'name') + interfaces = (Node, ) + + +class ArticleNode(MongoengineObjectType): + + class Meta: + model = models.Article + interfaces = (Node, ) + + +class EditorNode(MongoengineObjectType): + + class Meta: + model = models.Editor + interfaces = (Node, ) + + +class EmbeddedArticleNode(MongoengineObjectType): + + class Meta: + model = models.EmbeddedArticle + interfaces = (Node, ) + + +class PlayerNode(MongoengineObjectType): + + class Meta: + model = models.Player + interfaces = (Node, ) + + +class ReporterNode(MongoengineObjectType): + + class Meta: + model = models.Reporter + interfaces = (Node, ) + + +class ParentNode(MongoengineObjectType): + + class Meta: + model = models.Parent + interfaces = (Node, ) + + +class ChildNode(MongoengineObjectType): + + class Meta: + model = models.Child + interfaces = (Node, ) + + +class ChildRegisteredBeforeNode(MongoengineObjectType): + + class Meta: + model = models.ChildRegisteredBefore + interfaces = (Node, ) + + +class ParentWithRelationshipNode(MongoengineObjectType): + + class Meta: + model = models.ParentWithRelationship + interfaces = (Node, ) + + +class ChildRegisteredAfterNode(MongoengineObjectType): + + class Meta: + model = models.ChildRegisteredAfter + interfaces = (Node, ) + + +class ProfessorVectorNode(MongoengineObjectType): + + class Meta: + model = models.ProfessorVector + interfaces = (Node, ) + + +class ErroneousModelNode(MongoengineObjectType): + class Meta: + model = models.ErroneousModel + interfaces = (Node, ) diff --git a/graphene_mongo/tests/setup.py b/graphene_mongo/tests/setup.py index f147209a..1a94ef74 100644 --- a/graphene_mongo/tests/setup.py +++ b/graphene_mongo/tests/setup.py @@ -63,6 +63,7 @@ def fixtures(): ) reporter1.embedded_articles = [embedded_article1, embedded_article2] reporter1.embedded_list_articles = [embedded_article2, embedded_article1] + reporter1.generic_reference = article1 reporter1.save() Player.drop_collection() diff --git a/graphene_mongo/tests/test_converter.py b/graphene_mongo/tests/test_converter.py index d5e36623..d5b9e05a 100644 --- a/graphene_mongo/tests/test_converter.py +++ b/graphene_mongo/tests/test_converter.py @@ -1,16 +1,10 @@ import graphene import mongoengine - -from graphene import ( - Dynamic, Node -) - from py.test import raises from .models import ( Article, Editor, EmbeddedArticle, Player, Reporter, - ProfessorMetadata, ProfessorVector, - Publisher) + ProfessorMetadata, ProfessorVector, Publisher) from .. import registry from ..converter import convert_mongoengine_field from ..fields import MongoengineConnectionField @@ -114,11 +108,11 @@ class E(MongoengineObjectType): class Meta: model = Editor - interfaces = (Node,) + interfaces = (graphene.Node,) dynamic_field = convert_mongoengine_field( EmbeddedArticle._fields['editor'], E._meta.registry) - assert isinstance(dynamic_field, Dynamic) + assert isinstance(dynamic_field, graphene.Dynamic) graphene_type = dynamic_field.get_type() assert isinstance(graphene_type, graphene.Field) assert graphene_type.type == E @@ -130,12 +124,12 @@ class P(MongoengineObjectType): class Meta: model = Publisher - interfaces = (Node,) + interfaces = (graphene.Node,) dynamic_field = convert_mongoengine_field( Editor._fields['company'], P._meta.registry) - assert isinstance(dynamic_field, Dynamic) + assert isinstance(dynamic_field, graphene.Dynamic) graphene_type = dynamic_field.get_type() assert isinstance(graphene_type, graphene.Field) assert graphene_type.type == P @@ -147,11 +141,11 @@ class PM(MongoengineObjectType): class Meta: model = ProfessorMetadata - interfaces = (Node,) + interfaces = (graphene.Node,) dynamic_field = convert_mongoengine_field( ProfessorVector._fields['metadata'], PM._meta.registry) - assert isinstance(dynamic_field, Dynamic) + assert isinstance(dynamic_field, graphene.Dynamic) graphene_type = dynamic_field.get_type() assert isinstance(graphene_type, graphene.Field) assert graphene_type.type == PM @@ -161,7 +155,7 @@ def test_should_convert_none(): registry.reset_global_registry() dynamic_field = convert_mongoengine_field( EmbeddedArticle._fields['editor'], registry.get_global_registry()) - assert isinstance(dynamic_field, Dynamic) + assert isinstance(dynamic_field, graphene.Dynamic) graphene_type = dynamic_field.get_type() assert graphene_type is None @@ -170,7 +164,7 @@ def test_should_convert_none_lazily(): registry.reset_global_registry() dynamic_field = convert_mongoengine_field( Editor._fields['company'], registry.get_global_registry()) - assert isinstance(dynamic_field, Dynamic) + assert isinstance(dynamic_field, graphene.Dynamic) graphene_type = dynamic_field.get_type() assert graphene_type is None @@ -223,11 +217,11 @@ class P(MongoengineObjectType): class Meta: model = Player - interfaces = (Node,) + interfaces = (graphene.Node,) dynamic_field = convert_mongoengine_field( Player._fields['opponent'], P._meta.registry) - assert isinstance(dynamic_field, Dynamic) + assert isinstance(dynamic_field, graphene.Dynamic) graphene_type = dynamic_field.get_type() assert isinstance(graphene_type, graphene.Field) assert graphene_type.type == P @@ -300,3 +294,28 @@ class Meta: Article._fields['editor'], A._meta.registry ).get_type() assert editor_field.description == "An Editor of a publication." + + +def test_should_generic_reference_convert_union(): + pass + """ + class A(MongoengineObjectType): + + class Meta: + model = Article + + class E(MongoengineObjectType): + + class Meta: + model = Editor + + class R(MongoengineObjectType): + + class Meta: + model = Reporter + + generic_reference_field = convert_mongoengine_field( + Reporter._fields['generic_reference'], registry.get_global_registry()) + assert isinstance(generic_reference_field, graphene.Field) + assert isinstance(generic_reference_field.type(), graphene.Union) + """ diff --git a/graphene_mongo/tests/test_fields.py b/graphene_mongo/tests/test_fields.py index 878dc16d..e5ff6268 100644 --- a/graphene_mongo/tests/test_fields.py +++ b/graphene_mongo/tests/test_fields.py @@ -1,10 +1,10 @@ -from ..fields import MongoengineConnectionField -from .types import ArticleNode, PublisherNode, ReporterNode, ErroneousModelNode +from . import nodes from .setup import fixtures +from ..fields import MongoengineConnectionField def test_article_field_args(): - field = MongoengineConnectionField(ArticleNode) + field = MongoengineConnectionField(nodes.ArticleNode) field_args = ['id', 'headline', 'pub_date'] assert set(field.field_args.keys()) == set(field_args) @@ -18,35 +18,35 @@ def test_article_field_args(): def test_reporter_field_args(): - field = MongoengineConnectionField(ReporterNode) + field = MongoengineConnectionField(nodes.ReporterNode) field_args = ['id', 'first_name', 'last_name', 'email', 'awards'] assert set(field.field_args.keys()) == set(field_args) def test_field_args_with_property(): - field = MongoengineConnectionField(PublisherNode) + field = MongoengineConnectionField(nodes.PublisherNode) field_args = ['id', 'name'] assert set(field.field_args.keys()) == set(field_args) def test_field_args_with_unconverted_field(): - field = MongoengineConnectionField(PublisherNode) + field = MongoengineConnectionField(nodes.PublisherNode) field_args = ['id', 'name'] assert set(field.field_args.keys()) == set(field_args) def test_default_resolver_with_colliding_objects_field(): - field = MongoengineConnectionField(ErroneousModelNode) + field = MongoengineConnectionField(nodes.ErroneousModelNode) connection = field.default_resolver(None, {}) assert 0 == len(connection.iterable) def test_default_resolver_connection_list_length(fixtures): - field = MongoengineConnectionField(ArticleNode) + field = MongoengineConnectionField(nodes.ArticleNode) connection = field.default_resolver(None, {}, **{'first': 1}) assert hasattr(connection, 'list_length') diff --git a/graphene_mongo/tests/test_mutation.py b/graphene_mongo/tests/test_mutation.py index 9a2232b1..d18a525d 100644 --- a/graphene_mongo/tests/test_mutation.py +++ b/graphene_mongo/tests/test_mutation.py @@ -4,7 +4,7 @@ from .setup import fixtures from .models import (Article, Editor) -from .types import (ArticleNode, EditorNode) +from .nodes import (ArticleNode, EditorNode) def test_should_create(fixtures): diff --git a/graphene_mongo/tests/test_relay_query.py b/graphene_mongo/tests/test_relay_query.py index 1a7f6101..de210d79 100644 --- a/graphene_mongo/tests/test_relay_query.py +++ b/graphene_mongo/tests/test_relay_query.py @@ -7,7 +7,7 @@ from .setup import fixtures from .models import Article, Reporter -from .types import (ArticleNode, +from .nodes import (ArticleNode, EditorNode, PlayerNode, ReporterNode, @@ -57,6 +57,12 @@ def resolve_reporter(self, *args, **kwargs): headline } } + }, + genericReference { + __typename + ... on ArticleNode { + headline + } } } } @@ -108,6 +114,10 @@ def resolve_reporter(self, *args, **kwargs): } } ], + }, + 'genericReference': { + '__typename': 'ArticleNode', + 'headline': 'Hello' } } } @@ -779,16 +789,16 @@ class Query(graphene.ObjectType): query = ''' query { - allProfessors { - edges { - node { - vec, - metadata { - firstName + allProfessors { + edges { + node { + vec, + metadata { + firstName + } } } } - } } ''' expected = { diff --git a/graphene_mongo/tests/test_types.py b/graphene_mongo/tests/test_types.py index 620febca..dded8558 100644 --- a/graphene_mongo/tests/test_types.py +++ b/graphene_mongo/tests/test_types.py @@ -66,7 +66,8 @@ def test_objecttype_registered(): 'embedded_articles', 'embedded_list_articles', 'articles', - 'awards' + 'awards', + 'generic_reference', ]) diff --git a/graphene_mongo/tests/types.py b/graphene_mongo/tests/types.py index 826c4b25..b9a17797 100644 --- a/graphene_mongo/tests/types.py +++ b/graphene_mongo/tests/types.py @@ -1,169 +1,68 @@ -import graphene -from graphene.relay import Node - +from . import models from ..types import MongoengineObjectType -from .models import ( - Article, Editor, EmbeddedArticle, Player, Reporter, - Parent, Child, ProfessorMetadata, ProfessorVector, - ParentWithRelationship, ChildRegisteredBefore, - ChildRegisteredAfter, CellTower, - Publisher, ErroneousModel) class PublisherType(MongoengineObjectType): class Meta: - model = Publisher + model = models.Publisher class EditorType(MongoengineObjectType): class Meta: - model = Editor + model = models.Editor class ArticleType(MongoengineObjectType): class Meta: - model = Article + model = models.Article class EmbeddedArticleType(MongoengineObjectType): class Meta: - model = EmbeddedArticle + model = models.EmbeddedArticle class PlayerType(MongoengineObjectType): class Meta: - model = Player + model = models.Player class ReporterType(MongoengineObjectType): class Meta: - model = Reporter + model = models.Reporter class ParentType(MongoengineObjectType): class Meta: - model = Parent + model = models.Parent class ChildType(MongoengineObjectType): class Meta: - model = Child + model = models.Child class CellTowerType(MongoengineObjectType): class Meta: - model = CellTower + model = models.CellTower class ProfessorMetadataType(MongoengineObjectType): class Meta: - model = ProfessorMetadata + model = models.ProfessorMetadata class ProfessorVectorType(MongoengineObjectType): class Meta: - model = ProfessorVector - - -class PublisherNode(MongoengineObjectType): - legal_name = graphene.String() - bad_field = graphene.String() - - class Meta: - model = Publisher - only_fields = ('id', 'name') - interfaces = (Node,) - - -class ArticleNode(MongoengineObjectType): - - class Meta: - model = Article - interfaces = (Node,) - - -class EditorNode(MongoengineObjectType): - - class Meta: - model = Editor - interfaces = (Node,) - - -class EmbeddedArticleNode(MongoengineObjectType): - - class Meta: - model = EmbeddedArticle - interfaces = (Node,) - - -class PlayerNode(MongoengineObjectType): - - class Meta: - model = Player - interfaces = (Node,) - - -class ReporterNode(MongoengineObjectType): - - class Meta: - model = Reporter - interfaces = (Node,) - - -class ParentNode(MongoengineObjectType): - - class Meta: - model = Parent - interfaces = (Node,) - - -class ChildNode(MongoengineObjectType): - - class Meta: - model = Child - interfaces = (Node,) - - -class ChildRegisteredBeforeNode(MongoengineObjectType): - - class Meta: - model = ChildRegisteredBefore - interfaces = (Node, ) - - -class ParentWithRelationshipNode(MongoengineObjectType): - - class Meta: - model = ParentWithRelationship - interfaces = (Node, ) - - -class ChildRegisteredAfterNode(MongoengineObjectType): - - class Meta: - model = ChildRegisteredAfter - interfaces = (Node, ) - - -class ProfessorVectorNode(MongoengineObjectType): - - class Meta: - model = ProfessorVector - interfaces = (Node, ) - - -class ErroneousModelNode(MongoengineObjectType): - class Meta: - model = ErroneousModel - interfaces = (Node,) + model = models.ProfessorVector diff --git a/graphene_mongo/types.py b/graphene_mongo/types.py index 0840844a..84844880 100644 --- a/graphene_mongo/types.py +++ b/graphene_mongo/types.py @@ -1,10 +1,10 @@ -from collections import OrderedDict +import graphene +import mongoengine -from graphene import Field, ConnectionField +from collections import OrderedDict from graphene.relay import Connection, Node from graphene.types.objecttype import ObjectType, ObjectTypeOptions from graphene.types.utils import yank_fields_from_attrs -from mongoengine import ListField from graphene_mongo import MongoengineConnectionField from .converter import convert_mongoengine_field @@ -13,6 +13,17 @@ def construct_fields(model, registry, only_fields, exclude_fields): + """ + Args: + model (mongoengine.Document): + registry (graphene_mongo.registry.Registry): + only_fields ([str]): + exclude_fields ([str]): + + Returns: + (OrderedDict, OrderedDict): coverted fields and self reference fields. + + """ _model_fields = get_model_fields(model) fields = OrderedDict() self_referenced = OrderedDict() @@ -23,7 +34,7 @@ def construct_fields(model, registry, only_fields, exclude_fields): # We skip this field if we specify only_fields and is not # in there. Or when we exclude this field in exclude_fields continue - if isinstance(field, ListField): + if isinstance(field, mongoengine.ListField): # 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 \ @@ -78,11 +89,10 @@ def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=Fa 'The attribute registry in {}.Meta needs to be an instance of ' 'Registry, received "{}".' ).format(cls.__name__, registry) - converted_fields, self_referenced = construct_fields( model, registry, only_fields, exclude_fields ) - mongoengine_fields = yank_fields_from_attrs(converted_fields, _as=Field) + mongoengine_fields = yank_fields_from_attrs(converted_fields, _as=graphene.Field) if use_connection is None and interfaces: use_connection = any((issubclass(interface, Node) for interface in interfaces)) @@ -101,8 +111,8 @@ def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=Fa ).format(cls.__name__, type(connection)) if connection_field_class is not None: - assert issubclass(connection_field_class, ConnectionField), ( - 'The attribute connection_field_class in {}.Meta must be of type ConnectionField. ' + assert issubclass(connection_field_class, graphene.ConnectionField), ( + 'The attribute connection_field_class in {}.Meta must be of type graphene.ConnectionField. ' 'Received "{}" instead.' ).format(cls.__name__, type(connection_field_class)) else: @@ -128,7 +138,7 @@ def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=Fa # Notes: Take care list of self-reference fields. converted_fields = construct_self_referenced_fields(self_referenced, registry) if converted_fields: - mongoengine_fields = yank_fields_from_attrs(converted_fields, _as=Field) + mongoengine_fields = yank_fields_from_attrs(converted_fields, _as=graphene.Field) cls._meta.fields.update(mongoengine_fields) registry.register(cls) @@ -141,7 +151,7 @@ def rescan_fields(cls): cls._meta.only_fields, cls._meta.exclude_fields ) - mongoengine_fields = yank_fields_from_attrs(converted_fields, _as=Field) + mongoengine_fields = yank_fields_from_attrs(converted_fields, _as=graphene.Field) # The initial scan should take precidence for field in mongoengine_fields: diff --git a/setup.py b/setup.py index 7a095168..287525d9 100644 --- a/setup.py +++ b/setup.py @@ -7,14 +7,10 @@ description='Graphene Mongoengine integration', long_description=open('README.rst').read(), # long_description_content_type='text/markdown', - url='https://github.com/graphql-python/graphene-mongo', - author='Abaw Chen', author_email='abaw.chen@gmail.com', - license='MIT', - classifiers=[ 'Development Status :: 3 - Alpha', 'Intended Audience :: Developers', @@ -25,11 +21,8 @@ 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: Implementation :: PyPy', ], - keywords='api graphql protocol rest relay graphene mongo mongoengine', - packages=find_packages(exclude=['tests']), - install_requires=[ 'graphene>=2.1.3,<3', 'mongoengine>=0.15.0',