Improved Django integration.

This commit is contained in:
Syrus Akbary 2016-08-14 10:57:08 -07:00
parent dbc981c6d2
commit 26f364de0b
11 changed files with 184 additions and 149 deletions

View File

@ -1,11 +1,11 @@
from django.db import models
from django.utils.encoding import force_text
from graphene import Enum, List, ID, Boolean, Float, Int, String, Field, NonNull
from graphene import Enum, List, ID, Boolean, Float, Int, String, Field, NonNull, Field, Dynamic
from graphene.types.json import JSONString
from graphene.types.datetime import DateTime
from graphene.utils.str_converters import to_const
from graphene.relay import Node
from graphene.relay import is_node
from .compat import (ArrayField, HStoreField, JSONField, RangeField,
RelatedObject, UUIDField)
@ -92,7 +92,11 @@ def convert_date_to_string(field, registry=None):
@convert_django_field.register(models.OneToOneRel)
def convert_onetoone_field_to_djangomodel(field, registry=None):
model = get_related_model(field)
return Field(registry.get_type_for_model(model))
def dynamic_type():
return Field(registry.get_type_for_model(model))
return Dynamic(dynamic_type)
@convert_django_field.register(models.ManyToManyField)
@ -100,31 +104,46 @@ def convert_onetoone_field_to_djangomodel(field, registry=None):
@convert_django_field.register(models.ManyToOneRel)
def convert_field_to_list_or_connection(field, registry=None):
model = get_related_model(field)
_type = registry.get_type_for_model(model)
if not _type:
return
if issubclass(_type, Node):
return get_connection_field(_type)
return Field(List(_type))
def dynamic_type():
_type = registry.get_type_for_model(model)
if not _type:
return
if is_node(_type):
return get_connection_field(_type)
return Field(List(_type))
return Dynamic(dynamic_type)
# For Django 1.6
@convert_django_field.register(RelatedObject)
def convert_relatedfield_to_djangomodel(field, registry=None):
model = field.model
_type = registry.get_type_for_model(model)
if issubclass(_type, Node):
return get_connection_field(_type)
return List(_type)
def dynamic_type():
_type = registry.get_type_for_model(model)
if not _type:
return
if is_node(_type):
return get_connection_field(_type)
return Field(List(_type))
return Dynamic(dynamic_type)
@convert_django_field.register(models.OneToOneField)
@convert_django_field.register(models.ForeignKey)
def convert_field_to_djangomodel(field, registry=None):
model = get_related_model(field)
_type = registry.get_type_for_model(model)
return Field(_type, description=field.help_text)
def dynamic_type():
_type = registry.get_type_for_model(model)
return Field(_type, description=field.help_text)
return Dynamic(dynamic_type)
@convert_django_field.register(ArrayField)

View File

@ -21,7 +21,7 @@ class DjangoConnectionField(ConnectionField):
return self.model._default_manager
def default_resolver(self, root, args, context, info):
return getattr(root, self.source or self.attname, self.get_manager())
return getattr(root, self.source, self.get_manager())
@staticmethod
def connection_resolver(resolver, connection, root, args, context, info):

View File

@ -1,7 +1,7 @@
from ..fields import DjangoConnectionField
from .utils import get_filtering_args_from_filterset, get_filterset_class
from graphene.types.argument import to_arguments
# from graphene.types.argument import to_arguments
class DjangoFilterConnectionField(DjangoConnectionField):
@ -19,7 +19,8 @@ class DjangoFilterConnectionField(DjangoConnectionField):
self.filterset_class = get_filterset_class(filterset_class, **meta)
self.filtering_args = get_filtering_args_from_filterset(self.filterset_class, type)
kwargs.setdefault('args', {})
kwargs['args'].update(to_arguments(self.filtering_args))
kwargs['args'].update(self.filtering_args)
# kwargs['args'].update(to_arguments(self.filtering_args))
super(DjangoFilterConnectionField, self).__init__(type, *args, **kwargs)
def get_queryset(self, qs, args, info):

View File

@ -21,22 +21,25 @@ else:
pytestmark.append(pytest.mark.django_db)
class ArticleNode(DjangoNode, DjangoObjectType):
class ArticleNode(DjangoObjectType):
class Meta:
model = Article
interfaces = (DjangoNode, )
class ReporterNode(DjangoNode, DjangoObjectType):
class ReporterNode(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (DjangoNode, )
class PetNode(DjangoNode, DjangoObjectType):
class PetNode(DjangoObjectType):
class Meta:
model = Pet
interfaces = (DjangoNode, )
# schema = Schema()
@ -49,7 +52,7 @@ def get_args(field):
def assert_arguments(field, *arguments):
ignore = ('after', 'before', 'first', 'last', 'orderBy')
ignore = ('after', 'before', 'first', 'last', 'order_by')
args = get_args(field)
actual = [
name
@ -65,21 +68,21 @@ def assert_arguments(field, *arguments):
def assert_orderable(field):
args = get_args(field)
assert 'orderBy' in args, \
assert 'order_by' in args, \
'Field cannot be ordered'
def assert_not_orderable(field):
args = get_args(field)
assert 'orderBy' not in args, \
assert 'order_by' not in args, \
'Field can be ordered'
def test_filter_explicit_filterset_arguments():
field = DjangoFilterConnectionField(ArticleNode, filterset_class=ArticleFilter)
assert_arguments(field,
'headline', 'headline_Icontains',
'pubDate', 'pubDate_Gt', 'pubDate_Lt',
'headline', 'headline__icontains',
'pub_date', 'pub_date__gt', 'pub_date__lt',
'reporter',
)
@ -87,7 +90,7 @@ def test_filter_explicit_filterset_arguments():
def test_filter_shortcut_filterset_arguments_list():
field = DjangoFilterConnectionField(ArticleNode, fields=['pub_date', 'reporter'])
assert_arguments(field,
'pubDate',
'pub_date',
'reporter',
)
@ -98,7 +101,7 @@ def test_filter_shortcut_filterset_arguments_dict():
'reporter': ['exact'],
})
assert_arguments(field,
'headline', 'headline_Icontains',
'headline', 'headline__icontains',
'reporter',
)
@ -131,30 +134,33 @@ def test_filter_shortcut_filterset_extra_meta():
def test_filter_filterset_information_on_meta():
class ReporterFilterNode(DjangoNode, DjangoObjectType):
class ReporterFilterNode(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (DjangoNode, )
filter_fields = ['first_name', 'articles']
filter_order_by = True
field = DjangoFilterConnectionField(ReporterFilterNode)
assert_arguments(field, 'firstName', 'articles')
assert_arguments(field, 'first_name', 'articles')
assert_orderable(field)
def test_filter_filterset_information_on_meta_related():
class ReporterFilterNode(DjangoNode, DjangoObjectType):
class ReporterFilterNode(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (DjangoNode, )
filter_fields = ['first_name', 'articles']
filter_order_by = True
class ArticleFilterNode(DjangoNode, DjangoObjectType):
class ArticleFilterNode(DjangoObjectType):
class Meta:
model = Article
interfaces = (DjangoNode, )
filter_fields = ['headline', 'reporter']
filter_order_by = True
@ -165,22 +171,24 @@ def test_filter_filterset_information_on_meta_related():
article = Field(ArticleFilterNode)
schema = Schema(query=Query)
articles_field = ReporterFilterNode._meta.graphql_type.get_fields()['articles']
articles_field = ReporterFilterNode._meta.fields['articles'].get_type()
assert_arguments(articles_field, 'headline', 'reporter')
assert_orderable(articles_field)
def test_filter_filterset_related_results():
class ReporterFilterNode(DjangoNode, DjangoObjectType):
class ReporterFilterNode(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (DjangoNode, )
filter_fields = ['first_name', 'articles']
filter_order_by = True
class ArticleFilterNode(DjangoNode, DjangoObjectType):
class ArticleFilterNode(DjangoObjectType):
class Meta:
interfaces = (DjangoNode, )
model = Article
filter_fields = ['headline', 'reporter']
filter_order_by = True

View File

@ -5,20 +5,22 @@ from ..types import DjangoNode, DjangoObjectType
from .models import Article, Reporter
class Character(DjangoNode, DjangoObjectType):
class Character(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (DjangoNode, )
def get_node(self, id, context, info):
pass
class Human(DjangoNode, DjangoObjectType):
class Human(DjangoObjectType):
raises = graphene.String()
class Meta:
model = Article
interfaces = (DjangoNode, )
def resolve_raises(self, *args):
raise Exception("This field should raise exception")

View File

@ -7,7 +7,6 @@ import graphene
from graphene.relay import Node, ConnectionField
from graphene.types.datetime import DateTime
from graphene.types.json import JSONString
from graphene.utils.get_graphql_type import get_graphql_type
# from graphene.core.types.custom_scalars import DateTime, JSONString
from ..compat import (ArrayField, HStoreField, JSONField, MissingType,
@ -22,7 +21,7 @@ def assert_conversion(django_field, graphene_field, *args, **kwargs):
field = django_field(help_text='Custom Help Text', *args, **kwargs)
graphene_type = convert_django_field(field)
assert isinstance(graphene_type, graphene_field)
field = graphene_type.as_field()
field = graphene_type.Field()
assert field.description == 'Custom Help Text'
return field
@ -95,7 +94,7 @@ def test_should_integer_convert_int():
def test_should_boolean_convert_boolean():
field = assert_conversion(models.BooleanField, graphene.NonNull)
assert field.type.of_type == get_graphql_type(graphene.Boolean)
assert field.type.of_type == graphene.Boolean
def test_should_nullboolean_convert_boolean():
@ -116,7 +115,7 @@ def test_field_with_choices_convert_enum():
graphene_type = convert_django_field_with_choices(field)
assert isinstance(graphene_type, graphene.Enum)
assert graphene_type._meta.graphql_type.name == 'TranslatedModelLanguage'
assert graphene_type._meta.name == 'TranslatedModelLanguage'
assert graphene_type._meta.enum.__members__['SPANISH'].value == 'es'
assert graphene_type._meta.enum.__members__['ENGLISH'].value == 'en'
@ -159,8 +158,8 @@ def test_should_float_convert_float():
def test_should_manytomany_convert_connectionorlist():
registry = Registry()
graphene_field = convert_django_field(Reporter._meta.local_many_to_many[0], registry)
assert not graphene_field
dynamic_field = convert_django_field(Reporter._meta.local_many_to_many[0], registry)
assert not dynamic_field.get_type()
def test_should_manytomany_convert_connectionorlist_list():
@ -169,19 +168,24 @@ def test_should_manytomany_convert_connectionorlist_list():
model = Reporter
graphene_field = convert_django_field(Reporter._meta.local_many_to_many[0], A._meta.registry)
assert isinstance(graphene_field, graphene.Field)
assert isinstance(graphene_field.type, graphene.List)
assert graphene_field.type.of_type == get_graphql_type(A)
assert isinstance(graphene_field, graphene.Dynamic)
dynamic_field = graphene_field.get_type()
assert isinstance(dynamic_field, graphene.Field)
assert isinstance(dynamic_field.type, graphene.List)
assert dynamic_field.type.of_type == A
def test_should_manytomany_convert_connectionorlist_connection():
class A(DjangoNode, DjangoObjectType):
class A(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (DjangoNode, )
graphene_field = convert_django_field(Reporter._meta.local_many_to_many[0], A._meta.registry)
assert isinstance(graphene_field, ConnectionField)
assert graphene_field.type == get_graphql_type(A.get_default_connection())
assert isinstance(graphene_field, graphene.Dynamic)
dynamic_field = graphene_field.get_type()
assert isinstance(dynamic_field, ConnectionField)
assert dynamic_field.type == A.Connection
def test_should_manytoone_convert_connectionorlist():
@ -194,9 +198,11 @@ def test_should_manytoone_convert_connectionorlist():
model = Article
graphene_field = convert_django_field(related, A._meta.registry)
assert isinstance(graphene_field, graphene.Field)
assert isinstance(graphene_field.type, graphene.List)
assert graphene_field.type.of_type == get_graphql_type(A)
assert isinstance(graphene_field, graphene.Dynamic)
dynamic_field = graphene_field.get_type()
assert isinstance(dynamic_field, graphene.Field)
assert isinstance(dynamic_field.type, graphene.List)
assert dynamic_field.type.of_type == A
def test_should_onetoone_reverse_convert_model():
@ -209,8 +215,10 @@ def test_should_onetoone_reverse_convert_model():
model = FilmDetails
graphene_field = convert_django_field(related, A._meta.registry)
assert isinstance(graphene_field, graphene.Field)
assert graphene_field.type == get_graphql_type(A)
assert isinstance(graphene_field, graphene.Dynamic)
dynamic_field = graphene_field.get_type()
assert isinstance(dynamic_field, graphene.Field)
assert dynamic_field.type == A
@pytest.mark.skipif(ArrayField is MissingType,
@ -218,7 +226,7 @@ def test_should_onetoone_reverse_convert_model():
def test_should_postgres_array_convert_list():
field = assert_conversion(ArrayField, graphene.List, models.CharField(max_length=100))
assert isinstance(field.type, graphene.List)
assert field.type.of_type == get_graphql_type(graphene.String)
assert field.type.of_type == graphene.String
@pytest.mark.skipif(ArrayField is MissingType,
@ -227,7 +235,7 @@ def test_should_postgres_array_multiple_convert_list():
field = assert_conversion(ArrayField, graphene.List, ArrayField(models.CharField(max_length=100)))
assert isinstance(field.type, graphene.List)
assert isinstance(field.type.of_type, graphene.List)
assert field.type.of_type.of_type == get_graphql_type(graphene.String)
assert field.type.of_type.of_type == graphene.String
@pytest.mark.skipif(HStoreField is MissingType,
@ -248,4 +256,4 @@ def test_should_postgres_range_convert_list():
from django.contrib.postgres.fields import IntegerRangeField
field = assert_conversion(IntegerRangeField, graphene.List)
assert isinstance(field.type, graphene.List)
assert field.type.of_type == get_graphql_type(graphene.Int)
assert field.type.of_type == graphene.Int

View File

@ -3,7 +3,7 @@ from py.test import raises
import graphene
from ..form_converter import convert_form_field
from graphene import ID, List
from graphene import ID, List, NonNull
from graphene.utils.get_graphql_type import get_graphql_type
from .models import Reporter
@ -13,7 +13,7 @@ def assert_conversion(django_field, graphene_field, *args):
field = django_field(*args, help_text='Custom Help Text')
graphene_type = convert_form_field(field)
assert isinstance(graphene_type, graphene_field)
field = graphene_type.as_field()
field = graphene_type.Field()
assert field.description == 'Custom Help Text'
return field
@ -75,12 +75,12 @@ def test_should_integer_convert_int():
def test_should_boolean_convert_boolean():
field = assert_conversion(forms.BooleanField, graphene.Boolean)
assert field.required is True
assert isinstance(field.type, NonNull)
def test_should_nullboolean_convert_boolean():
field = assert_conversion(forms.NullBooleanField, graphene.Boolean)
assert field.required is False
assert not isinstance(field.type, NonNull)
def test_should_float_convert_float():
@ -95,7 +95,7 @@ def test_should_multiple_choice_convert_connectionorlist():
field = forms.ModelMultipleChoiceField(Reporter.objects.all())
graphene_type = convert_form_field(field)
assert isinstance(graphene_type, List)
assert graphene_type.of_type == get_graphql_type(ID)
assert graphene_type.of_type == ID
def test_should_manytoone_convert_connectionorlist():

View File

@ -121,10 +121,11 @@ def test_should_node():
# reset_global_registry()
# DjangoNode._meta.registry = get_global_registry()
class ReporterNode(DjangoNode, DjangoObjectType):
class ReporterNode(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (DjangoNode, )
@classmethod
def get_node(cls, id, context, info):
@ -133,10 +134,11 @@ def test_should_node():
def resolve_articles(self, *args, **kwargs):
return [Article(headline='Hi!')]
class ArticleNode(DjangoNode, DjangoObjectType):
class ArticleNode(DjangoObjectType):
class Meta:
model = Article
interfaces = (DjangoNode, )
@classmethod
def get_node(cls, id, context, info):

View File

@ -27,7 +27,7 @@ def test_should_map_fields_correctly():
class Meta:
model = Reporter
registry = Registry()
assert list(ReporterType2._meta.graphql_type.get_fields().keys()) == ['id', 'firstName', 'lastName', 'email', 'pets', 'aChoice']
assert list(ReporterType2._meta.fields.keys()) == ['id', 'first_name', 'last_name', 'email', 'pets', 'a_choice', 'articles', 'films']
def test_should_map_only_few_fields():
@ -35,6 +35,6 @@ def test_should_map_only_few_fields():
class Meta:
model = Reporter
fields = ('id', 'email')
only_fields = ('id', 'email')
assert list(Reporter2._meta.graphql_type.get_fields().keys()) == ['id', 'email']
assert list(Reporter2._meta.fields.keys()) == ['id', 'email']

View File

@ -6,21 +6,22 @@ from graphene.relay import Node, ConnectionField
from ..types import DjangoNode, DjangoObjectType
from .models import Article as ArticleModel, Reporter as ReporterModel
from ..registry import reset_global_registry, Registry
reset_global_registry()
class Reporter(DjangoObjectType):
'''Character description'''
'''Reporter description'''
class Meta:
model = ReporterModel
class Article(DjangoNode, DjangoObjectType):
'''Human description'''
pub_date = Int()
class Article(DjangoObjectType):
'''Article description'''
class Meta:
model = ArticleModel
interfaces = (DjangoNode, )
class RootQuery(ObjectType):
@ -43,13 +44,13 @@ def test_django_get_node(get):
def test_django_objecttype_map_correct_fields():
graphql_type = Reporter._meta.graphql_type
assert list(graphql_type.get_fields().keys()) == ['id', 'firstName', 'lastName', 'email', 'pets', 'aChoice', 'articles']
fields = Reporter._meta.fields
assert list(fields.keys()) == ['id', 'first_name', 'last_name', 'email', 'pets', 'a_choice', 'articles', 'films']
def test_django_objecttype_with_node_have_correct_fields():
graphql_type = Article._meta.graphql_type
assert list(graphql_type.get_fields().keys()) == ['id', 'pubDate', 'headline', 'reporter', 'lang', 'importance']
fields = Article._meta.fields
assert list(fields.keys()) == ['id', 'headline', 'pub_date', 'reporter', 'lang', 'importance']
def test_schema_representation():
@ -60,8 +61,8 @@ schema {
type Article implements Node {
id: ID!
pubDate: Int
headline: String
pubDate: DateTime
reporter: Reporter
lang: ArticleLang
importance: ArticleImportance
@ -87,6 +88,8 @@ enum ArticleLang {
ENGLISH
}
scalar DateTime
interface Node {
id: ID!
}

View File

@ -1,9 +1,10 @@
from collections import OrderedDict
from functools import partial
import six
from graphene import Field, Interface
from graphene.types.objecttype import ObjectType, ObjectTypeMeta, attrs_without_fields, get_interfaces
from graphene import Field, Interface, ObjectType
from graphene.types.objecttype import ObjectTypeMeta
from graphene.relay import Node
from graphene.relay.node import NodeMeta
from .converter import convert_django_field_with_choices
@ -11,22 +12,18 @@ from graphene.types.options import Options
from .utils import get_model_fields, is_valid_django_model, DJANGO_FILTER_INSTALLED
from .registry import Registry, get_global_registry
from graphene.utils.is_base_type import is_base_type
from graphene.utils.copy_fields import copy_fields
from graphene.utils.get_graphql_type import get_graphql_type
from graphene.utils.get_fields import get_fields
from graphene.utils.as_field import as_field
from graphene.generators import generate_objecttype
from graphene.types.utils import get_fields_in_type
class DjangoObjectTypeMeta(ObjectTypeMeta):
def _construct_fields(cls, fields, options):
def _construct_fields(cls, all_fields, options):
_model_fields = get_model_fields(options.model)
fields = OrderedDict()
for field in _model_fields:
name = field.name
is_not_in_only = options.fields and name not in options.fields
is_already_created = name in fields
is_excluded = field.name in options.exclude or is_already_created
is_not_in_only = options.only_fields and name not in options.only_fields
is_already_created = name in all_fields
is_excluded = name in options.exclude_fields or is_already_created
if is_not_in_only or is_excluded:
# We skip this field if we specify only_fields and is not
# in there. Or when we exclude this field in exclude_fields
@ -34,28 +31,24 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
converted = convert_django_field_with_choices(field, options.registry)
if not converted:
continue
fields[name] = as_field(converted)
fields = copy_fields(Field, fields, parent=cls)
fields[name] = converted
return fields
@staticmethod
def _create_objecttype(cls, name, bases, attrs):
# super_new = super(DjangoObjectTypeMeta, cls).__new__
super_new = type.__new__
# Also ensure initialization is only performed for subclasses of Model
# (excluding Model class itself).
def __new__(cls, name, bases, attrs):
# Also ensure initialization is only performed for subclasses of
# DjangoObjectType
if not is_base_type(bases, DjangoObjectTypeMeta):
return super_new(cls, name, bases, attrs)
return type.__new__(cls, name, bases, attrs)
defaults = dict(
name=None,
description=None,
name=name,
description=attrs.pop('__doc__', None),
model=None,
fields=(),
exclude=(),
fields=None,
only_fields=(),
exclude_fields=(),
interfaces=(),
registry=None
)
@ -73,52 +66,40 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
)
if not options.registry:
options.registry = get_global_registry()
assert isinstance(options.registry, Registry), 'The attribute registry in {}.Meta needs to be an instance of Registry, received "{}".'.format(name, options.registry)
assert is_valid_django_model(options.model), 'You need to pass a valid Django Model in {}.Meta, received "{}".'.format(name, options.model)
assert isinstance(options.registry, Registry), (
'The attribute registry in {}.Meta needs to be an instance of '
'Registry, received "{}".'
).format(name, options.registry)
assert is_valid_django_model(options.model), (
'You need to pass a valid Django Model in {}.Meta, received "{}".'
).format(name, options.model)
interfaces = tuple(options.interfaces)
fields = get_fields(ObjectType, attrs, bases, interfaces)
attrs = attrs_without_fields(attrs, fields)
cls = super_new(cls, name, bases, dict(attrs, _meta=options))
# interfaces = tuple(options.interfaces)
# fields = get_fields(ObjectType, attrs, bases, interfaces)
# attrs = attrs_without_fields(attrs, fields)
cls = ObjectTypeMeta.__new__(cls, name, bases, dict(attrs, _meta=options))
base_interfaces = tuple(b for b in bases if issubclass(b, Interface))
options.get_fields = partial(cls._construct_fields, fields, options)
options.get_interfaces = tuple(get_interfaces(interfaces + base_interfaces))
options.registry.register(cls)
options.graphql_type = generate_objecttype(cls)
if issubclass(cls, DjangoObjectType):
options.registry.register(cls)
options.django_fields = get_fields_in_type(
ObjectType,
cls._construct_fields(options.fields, options)
)
options.fields.update(options.django_fields)
return cls
class DjangoObjectType(six.with_metaclass(DjangoObjectTypeMeta, ObjectType)):
is_type_of = None
@classmethod
def is_type_of(cls, root, context, info):
if isinstance(root, cls):
return True
if not is_valid_django_model(type(root)):
raise Exception('Received incompatible instance "{}"'.format(root))
model = root._meta.model
return model == cls._meta.model
class DjangoNodeMeta(DjangoObjectTypeMeta, NodeMeta):
@staticmethod
def _get_interface_options(meta):
return Options(
meta,
name=None,
description=None,
graphql_type=None,
registry=False
)
@staticmethod
def _create_interface(cls, name, bases, attrs):
cls = super(DjangoNodeMeta, cls)._create_interface(cls, name, bases, attrs)
if not cls._meta.registry:
cls._meta.registry = get_global_registry()
assert isinstance(cls._meta.registry, Registry), 'The attribute registry in {}.Meta needs to be an instance of Registry.'.format(name)
return cls
class DjangoNode(six.with_metaclass(DjangoNodeMeta, Node)):
@classmethod
def get_node(cls, id, context, info):
try:
@ -126,12 +107,23 @@ class DjangoNode(six.with_metaclass(DjangoNodeMeta, Node)):
except cls._meta.model.DoesNotExist:
return None
@classmethod
def resolve_type(cls, type, context, info):
# We get the model from the _meta in the Django class/instance
model = type._meta.model
graphene_type = cls._meta.registry.get_type_for_model(model)
if graphene_type:
return get_graphql_type(graphene_type)
DjangoNode = Node
raise Exception("Type not found for model \"{}\"".format(model))
# class DjangoNodeMeta(DjangoObjectTypeMeta, NodeMeta):
# pass
# class DjangoNode(six.with_metaclass(DjangoNodeMeta, Node)):
# @classmethod
# def get_node(cls, id, context, info):
# try:
# return cls._meta.model.objects.get(id=id)
# except cls._meta.model.DoesNotExist:
# return None
# @classmethod
# def resolve_type(cls, type, context, info):
# # We get the model from the _meta in the Django class/instance
# model = type._meta.model
# graphene_type = cls._meta.registry.get_type_for_model(model)
# return graphene_type