Skip to content
This repository was archived by the owner on Sep 6, 2022. It is now read-only.

Commit 725763c

Browse files
committed
Better NdbKeyStringField implementation
1 parent 3dfa734 commit 725763c

File tree

3 files changed

+45
-21
lines changed

3 files changed

+45
-21
lines changed

graphene_gae/ndb/converter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def convert_ndb_key_propety(ndb_key_prop, meta):
9090
string_prop_name = singular_name + '_ids' if ndb_key_prop._repeated else singular_name + '_id'
9191
resolved_prop_name = name
9292

93-
string_field = NdbKeyStringField(name)
93+
string_field = NdbKeyStringField(name, ndb_key_prop._kind)
9494
resolved_field = NdbKeyField(name, ndb_key_prop._kind)
9595

9696
if ndb_key_prop._repeated:

graphene_gae/ndb/fields.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,54 +91,56 @@ def model(self):
9191

9292

9393
class NdbKeyStringField(String):
94-
def __init__(self, name, *args, **kwargs):
94+
def __init__(self, name, kind, *args, **kwargs):
9595
self.name = name
96+
self.kind = kind
9697

9798
if 'resolver' not in kwargs:
9899
kwargs['resolver'] = self.default_resolver
99100

100101
super(NdbKeyStringField, self).__init__(*args, **kwargs)
101102

102-
def default_resolver(self, node, args, info):
103-
entity = node.instance
104-
key = getattr(entity, self.name)
105-
if not key:
106-
return None
107-
108-
if isinstance(key, list):
109-
t = self.__get_key_internal_type(key[0], info.schema.graphene_schema)
110-
return [to_global_id(t.name, k.urlsafe()) for k in key]
111-
112-
t = self.__get_key_internal_type(key, info.schema.graphene_schema)
113-
return to_global_id(t.name, key.urlsafe()) if key else None
114-
115-
def __get_key_internal_type(self, key, schema):
116-
_type = self.__find_key_object_type(key, schema)
103+
def internal_type(self, schema):
104+
_type = self.get_object_type(schema)
117105
if not _type and self.parent._meta.only_fields:
118106
raise Exception(
119107
"Model %r is not accessible by the schema. "
120108
"You can either register the type manually "
121109
"using @schema.register. "
122110
"Or disable the field in %s" % (
123-
key.kind(),
111+
self.kind,
124112
self.parent,
125113
)
126114
)
127115

128116
if not _type:
129117
raise SkipField()
130118

131-
return schema.T(_type)
119+
from graphql import GraphQLString
120+
return GraphQLString
132121

133-
def __find_key_object_type(self, key, schema):
122+
def get_object_type(self, schema):
134123
for _type in schema.types.values():
135124
type_model = hasattr(_type, '_meta') and getattr(_type._meta, 'model', None)
136125
if not type_model:
137126
continue
138127

139-
if key.kind() == type_model or key.kind() == type_model.__name__:
128+
if self.kind == type_model or self.kind == type_model.__name__:
140129
return _type
141130

131+
def default_resolver(self, node, args, info):
132+
entity = node.instance
133+
key = getattr(entity, self.name)
134+
if not key:
135+
return None
136+
137+
if isinstance(key, list):
138+
t = self.get_object_type(info.schema.graphene_schema)._meta.type_name
139+
return [to_global_id(t, k.urlsafe()) for k in key]
140+
141+
t = self.get_object_type(info.schema.graphene_schema)._meta.type_name
142+
return to_global_id(t, key.urlsafe()) if key else None
143+
142144

143145
class NdbKeyField(FieldType):
144146
def __init__(self, name, kind, *args, **kwargs):

tests/_ndb/test_types.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from graphene_gae.ndb.fields import NdbKeyStringField
12
from graphql_relay import to_global_id
23
from tests.base_test import BaseTest
34

@@ -104,6 +105,27 @@ def resolve_articles(self):
104105

105106
self.assertIn("Model 'bar' is not accessible by the schema.", str(context.exception.message))
106107

108+
def testNdbObjectType_keyProperty_stringRepresentation_kindDoesntExist_raisesException(self):
109+
with self.assertRaises(Exception) as context:
110+
class ArticleType(NdbObjectType):
111+
class Meta:
112+
model = Article
113+
only_fields = ('prop',)
114+
115+
prop = NdbKeyStringField('foo', 'bar')
116+
117+
class QueryType(graphene.ObjectType):
118+
articles = graphene.List(ArticleType)
119+
120+
@graphene.resolve_only_args
121+
def resolve_articles(self):
122+
return Article.query()
123+
124+
schema = graphene.Schema(query=QueryType)
125+
result = schema.execute('query test { articles { prop } }')
126+
127+
self.assertIn("Model 'bar' is not accessible by the schema.", str(context.exception.message))
128+
107129
def testQuery_excludedField(self):
108130
Article(headline="h1", summary="s1").put()
109131

0 commit comments

Comments
 (0)