Skip to content

Commit db305b3

Browse files
committed
Don't break on inherited choices fields.
Store converted Django fields in the registry, so choices enums are not created multiple times when inherited by child models.
1 parent 1e34dfb commit db305b3

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

graphene_django/converter.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ def get_choices(choices):
4242

4343

4444
def convert_django_field_with_choices(field, registry=None):
45+
if registry:
46+
converted = registry.get_converted_field(field)
47+
if converted:
48+
return converted
4549
choices = getattr(field, 'choices', None)
4650
if choices:
4751
meta = field.model._meta
@@ -57,8 +61,12 @@ def description(self):
5761
return named_choices_descriptions[self.name]
5862

5963
enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType)
60-
return enum(description=field.help_text, required=not field.null)
61-
return convert_django_field(field, registry)
64+
converted = enum(description=field.help_text, required=not field.null)
65+
else:
66+
converted = convert_django_field(field, registry)
67+
if registry:
68+
registry.register_converted_field(field, converted)
69+
return converted
6270

6371

6472
@singledispatch

graphene_django/registry.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class Registry(object):
22

33
def __init__(self):
44
self._registry = {}
5-
self._registry_models = {}
5+
self._field_registry = {}
66

77
def register(self, cls):
88
from .types import DjangoObjectType
@@ -19,6 +19,12 @@ def register(self, cls):
1919
def get_type_for_model(self, model):
2020
return self._registry.get(model)
2121

22+
def register_converted_field(self, field, converted):
23+
self._field_registry[field] = converted
24+
25+
def get_converted_field(self, field):
26+
return self._field_registry.get(field)
27+
2228

2329
registry = None
2430

graphene_django/tests/test_query.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,3 +545,35 @@ class Query(graphene.ObjectType):
545545
assert result.data == expected
546546

547547
graphene_settings.RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST = False
548+
549+
550+
def test_should_handle_inherited_choices():
551+
class BaseModel(models.Model):
552+
choice_field = models.IntegerField(choices=((0, 'zero'), (1, 'one')))
553+
554+
class ChildModel(BaseModel):
555+
class Meta:
556+
proxy = True
557+
558+
class BaseType(DjangoObjectType):
559+
class Meta:
560+
model = BaseModel
561+
562+
class ChildType(DjangoObjectType):
563+
class Meta:
564+
model = ChildModel
565+
566+
class Query(graphene.ObjectType):
567+
base = graphene.Field(BaseType)
568+
child = graphene.Field(ChildType)
569+
570+
schema = graphene.Schema(query=Query)
571+
query = '''
572+
query {
573+
child {
574+
choiceField
575+
}
576+
}
577+
'''
578+
result = schema.execute(query)
579+
assert not result.errors

0 commit comments

Comments
 (0)