From 83bc32bc9d49c6f13bcac30463c244e4fa31403d Mon Sep 17 00:00:00 2001 From: Leeward Bound <395107+leewardbound@users.noreply.github.com> Date: Fri, 7 Feb 2020 17:17:56 +0700 Subject: [PATCH] Adding support for disabling enum creation on SerializerMutation (#851) --- graphene_django/rest_framework/mutation.py | 25 ++++++++++++++++--- .../rest_framework/serializer_converter.py | 7 ++++-- .../tests/test_field_converter.py | 18 +++++++++++-- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/graphene_django/rest_framework/mutation.py b/graphene_django/rest_framework/mutation.py index 060b370..cba6b47 100644 --- a/graphene_django/rest_framework/mutation.py +++ b/graphene_django/rest_framework/mutation.py @@ -19,7 +19,13 @@ class SerializerMutationOptions(MutationOptions): serializer_class = None -def fields_for_serializer(serializer, only_fields, exclude_fields, is_input=False): +def fields_for_serializer( + serializer, + only_fields, + exclude_fields, + is_input=False, + convert_choices_to_enum=True, +): fields = OrderedDict() for name, field in serializer.fields.items(): is_not_in_only = only_fields and name not in only_fields @@ -34,7 +40,9 @@ def fields_for_serializer(serializer, only_fields, exclude_fields, is_input=Fals if is_not_in_only or is_excluded: continue - fields[name] = convert_serializer_field(field, is_input=is_input) + fields[name] = convert_serializer_field( + field, is_input=is_input, convert_choices_to_enum=convert_choices_to_enum + ) return fields @@ -55,6 +63,7 @@ class SerializerMutation(ClientIDMutation): model_operations=("create", "update"), only_fields=(), exclude_fields=(), + convert_choices_to_enum=True, **options ): @@ -74,10 +83,18 @@ class SerializerMutation(ClientIDMutation): lookup_field = model_class._meta.pk.name input_fields = fields_for_serializer( - serializer, only_fields, exclude_fields, is_input=True + serializer, + only_fields, + exclude_fields, + is_input=True, + convert_choices_to_enum=convert_choices_to_enum, ) output_fields = fields_for_serializer( - serializer, only_fields, exclude_fields, is_input=False + serializer, + only_fields, + exclude_fields, + is_input=False, + convert_choices_to_enum=convert_choices_to_enum, ) _meta = SerializerMutationOptions(cls) diff --git a/graphene_django/rest_framework/serializer_converter.py b/graphene_django/rest_framework/serializer_converter.py index caeb7dd..82a113a 100644 --- a/graphene_django/rest_framework/serializer_converter.py +++ b/graphene_django/rest_framework/serializer_converter.py @@ -19,14 +19,17 @@ def get_graphene_type_from_serializer_field(field): ) -def convert_serializer_field(field, is_input=True): +def convert_serializer_field(field, is_input=True, convert_choices_to_enum=True): """ Converts a django rest frameworks field to a graphql field and marks the field as required if we are creating an input type and the field itself is required """ - graphql_type = get_graphene_type_from_serializer_field(field) + if isinstance(field, serializers.ChoiceField) and not convert_choices_to_enum: + graphql_type = graphene.String + else: + graphql_type = get_graphene_type_from_serializer_field(field) args = [] kwargs = {"description": field.help_text, "required": is_input and field.required} diff --git a/graphene_django/rest_framework/tests/test_field_converter.py b/graphene_django/rest_framework/tests/test_field_converter.py index 82f5b63..daa8349 100644 --- a/graphene_django/rest_framework/tests/test_field_converter.py +++ b/graphene_django/rest_framework/tests/test_field_converter.py @@ -10,7 +10,9 @@ from ..serializer_converter import convert_serializer_field from ..types import DictType -def _get_type(rest_framework_field, is_input=True, **kwargs): +def _get_type( + rest_framework_field, is_input=True, convert_choices_to_enum=True, **kwargs +): # prevents the following error: # AssertionError: The `source` argument is not meaningful when applied to a `child=` field. # Remove `source=` from the field declaration. @@ -21,7 +23,9 @@ def _get_type(rest_framework_field, is_input=True, **kwargs): field = rest_framework_field(**kwargs) - return convert_serializer_field(field, is_input=is_input) + return convert_serializer_field( + field, is_input=is_input, convert_choices_to_enum=convert_choices_to_enum + ) def assert_conversion(rest_framework_field, graphene_field, **kwargs): @@ -73,6 +77,16 @@ def test_should_choice_convert_enum(): assert field._meta.enum.__members__["W"].description == "World" +def test_should_choice_convert_string_if_enum_disabled(): + assert_conversion( + serializers.ChoiceField, + graphene.String, + choices=[("h", "Hello"), ("w", "World")], + source="word", + convert_choices_to_enum=False, + ) + + def test_should_base_field_convert_string(): assert_conversion(serializers.Field, graphene.String)