Skip to content

Commit be20450

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 2929d08 commit be20450

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
@@ -41,6 +41,10 @@ def get_choices(choices):
4141

4242

4343
def convert_django_field_with_choices(field, registry=None):
44+
if registry:
45+
converted = registry.get_converted_field(field)
46+
if converted:
47+
return converted
4448
choices = getattr(field, 'choices', None)
4549
if choices:
4650
meta = field.model._meta
@@ -56,8 +60,12 @@ def description(self):
5660
return named_choices_descriptions[self.name]
5761

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

6270

6371
@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
@@ -747,3 +747,35 @@ class Query(graphene.ObjectType):
747747
result = schema.execute(query)
748748
assert not result.errors
749749
assert result.data == expected
750+
751+
752+
def test_should_handle_inherited_choices():
753+
class BaseModel(models.Model):
754+
choice_field = models.IntegerField(choices=((0, 'zero'), (1, 'one')))
755+
756+
class ChildModel(BaseModel):
757+
class Meta:
758+
proxy = True
759+
760+
class BaseType(DjangoObjectType):
761+
class Meta:
762+
model = BaseModel
763+
764+
class ChildType(DjangoObjectType):
765+
class Meta:
766+
model = ChildModel
767+
768+
class Query(graphene.ObjectType):
769+
base = graphene.Field(BaseType)
770+
child = graphene.Field(ChildType)
771+
772+
schema = graphene.Schema(query=Query)
773+
query = '''
774+
query {
775+
child {
776+
choiceField
777+
}
778+
}
779+
'''
780+
result = schema.execute(query)
781+
assert not result.errors

0 commit comments

Comments
 (0)