From 9e007b962e2480e1619b5863ee52f4cd498f80c2 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Mon, 7 Jan 2019 09:03:37 -0500 Subject: [PATCH 1/8] Add converter to graphene_django --- graphene_django/forms/converter.py | 25 ++++++++++++++++++++++++- graphene_django/forms/mutation.py | 6 +++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/graphene_django/forms/converter.py b/graphene_django/forms/converter.py index 87180b2..07988f4 100644 --- a/graphene_django/forms/converter.py +++ b/graphene_django/forms/converter.py @@ -1,8 +1,10 @@ from django import forms from django.core.exceptions import ImproperlyConfigured -from graphene import ID, Boolean, Float, Int, List, String, UUID, Date, DateTime, Time +from graphene import ID, Boolean, Float, Int, List, String, UUID, Date, DateTime, Time, Enum +from graphene.utils.str_converters import to_camel_case +from graphene_django.converter import get_choices from .forms import GlobalIDFormField, GlobalIDMultipleChoiceField from ..utils import import_single_dispatch @@ -82,3 +84,24 @@ def convert_form_field_to_time(field): @convert_form_field.register(GlobalIDFormField) def convert_form_field_to_id(field): return ID(required=field.required) + + +@convert_form_field.register(forms.TypedChoiceField) +def convert_form_to_enum(field, name): + choices = getattr(field, 'choices', None) + name = to_camel_case(name) + choices = list(get_choices(choices)) + named_choices = [(c[0], c[1]) for c in choices] + named_choices_descriptions = {c[0]: c[2] for c in choices} + + class EnumWithDescriptionsType(object): + """Enum type definition""" + + @property + def description(self): + """Return field description""" + + return named_choices_descriptions[self.name] + + enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType) + return enum(description=field.help_text, required=field.required) diff --git a/graphene_django/forms/mutation.py b/graphene_django/forms/mutation.py index 63ea089..c39b3c3 100644 --- a/graphene_django/forms/mutation.py +++ b/graphene_django/forms/mutation.py @@ -30,7 +30,11 @@ def fields_for_form(form, only_fields, exclude_fields): if is_not_in_only or is_excluded: continue - fields[name] = convert_form_field(field) + choices = getattr(field, 'choices', None) + if choices: + fields[name] = convert_form_field(field, field.label or name) + else: + fields[name] = convert_form_field(field) return fields From b3d418253be972285b8cdadd041e08f084cfa915 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Mon, 7 Jan 2019 09:03:49 -0500 Subject: [PATCH 2/8] Add test to converter --- graphene_django/forms/tests/test_converter.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/graphene_django/forms/tests/test_converter.py b/graphene_django/forms/tests/test_converter.py index 955b952..f7b6f01 100644 --- a/graphene_django/forms/tests/test_converter.py +++ b/graphene_django/forms/tests/test_converter.py @@ -14,6 +14,7 @@ from graphene import ( DateTime, Date, Time, + Enum, ) from ..converter import convert_form_field @@ -112,3 +113,9 @@ def test_should_manytoone_convert_connectionorlist(): field = forms.ModelChoiceField(queryset=None) graphene_type = convert_form_field(field) assert isinstance(graphene_type, ID) + + +def test_should_typed_choice_convert_enum(): + field = forms.TypedChoiceField(choices=(('A', 'Choice A'), ('B', 'Choice B'))) + graphene_type = convert_form_field(field, 'field') + assert isinstance(graphene_type, Enum) From 8e2f626f350341d385784c1d8b54369fcb0bab66 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Fri, 1 Mar 2019 16:38:47 -0500 Subject: [PATCH 3/8] Set conversion to enum --- graphene_django/forms/converter.py | 36 +++++++++++-------- graphene_django/forms/mutation.py | 8 ++--- graphene_django/forms/tests/test_converter.py | 6 ++-- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/graphene_django/forms/converter.py b/graphene_django/forms/converter.py index 07988f4..8b92a8e 100644 --- a/graphene_django/forms/converter.py +++ b/graphene_django/forms/converter.py @@ -86,22 +86,30 @@ def convert_form_field_to_id(field): return ID(required=field.required) -@convert_form_field.register(forms.TypedChoiceField) -def convert_form_to_enum(field, name): +def convert_form_field_with_choices(name, field): + """ + Helper method to convert a field to graphene Field type. + :param name: form field's name + :param field: form field to convert to + :return: graphene Field + """ choices = getattr(field, 'choices', None) - name = to_camel_case(name) - choices = list(get_choices(choices)) - named_choices = [(c[0], c[1]) for c in choices] - named_choices_descriptions = {c[0]: c[2] for c in choices} - class EnumWithDescriptionsType(object): - """Enum type definition""" + if choices: + name = to_camel_case(field.label or name) + choices = list(get_choices(choices)) + named_choices = [(c[0], c[1]) for c in choices] + named_choices_descriptions = {c[0]: c[2] for c in choices} - @property - def description(self): - """Return field description""" + class EnumWithDescriptionsType(object): + """Enum type definition""" - return named_choices_descriptions[self.name] + @property + def description(self): + """Return field description""" - enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType) - return enum(description=field.help_text, required=field.required) + return named_choices_descriptions[self.name] + + enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType) + return enum(description=field.help_text, required=field.required) # pylint: disable=E1102 + return convert_form_field(field) diff --git a/graphene_django/forms/mutation.py b/graphene_django/forms/mutation.py index 1d1fe74..0b64c46 100644 --- a/graphene_django/forms/mutation.py +++ b/graphene_django/forms/mutation.py @@ -13,7 +13,7 @@ from graphene.types.mutation import MutationOptions from graphene.types.utils import yank_fields_from_attrs from graphene_django.registry import get_global_registry -from .converter import convert_form_field +from .converter import convert_form_field, convert_form_field_with_choices from .types import ErrorType @@ -30,11 +30,7 @@ def fields_for_form(form, only_fields, exclude_fields): if is_not_in_only or is_excluded: continue - choices = getattr(field, 'choices', None) - if choices: - fields[name] = convert_form_field(field, field.label or name) - else: - fields[name] = convert_form_field(field) + fields[name] = convert_form_field_with_choices(name, field) return fields diff --git a/graphene_django/forms/tests/test_converter.py b/graphene_django/forms/tests/test_converter.py index f7b6f01..6039eac 100644 --- a/graphene_django/forms/tests/test_converter.py +++ b/graphene_django/forms/tests/test_converter.py @@ -17,7 +17,7 @@ from graphene import ( Enum, ) -from ..converter import convert_form_field +from ..converter import convert_form_field, convert_form_field_with_choices def assert_conversion(django_field, graphene_field, *args): @@ -116,6 +116,6 @@ def test_should_manytoone_convert_connectionorlist(): def test_should_typed_choice_convert_enum(): - field = forms.TypedChoiceField(choices=(('A', 'Choice A'), ('B', 'Choice B'))) - graphene_type = convert_form_field(field, 'field') + field = forms.TypedChoiceField(choices=(('A', 'Choice A'), ('B', 'Choice B')), label='field') + graphene_type = convert_form_field_with_choices('field_name', field) assert isinstance(graphene_type, Enum) From 6ea5e2bbaf7de64e0bd68dd06a6470eae0fc2246 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Sun, 3 Mar 2019 15:33:11 -0500 Subject: [PATCH 4/8] Update converter --- graphene_django/forms/converter.py | 14 ++++++++++++-- graphene_django/forms/mutation.py | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/graphene_django/forms/converter.py b/graphene_django/forms/converter.py index 8b92a8e..bbaba98 100644 --- a/graphene_django/forms/converter.py +++ b/graphene_django/forms/converter.py @@ -86,7 +86,13 @@ def convert_form_field_to_id(field): return ID(required=field.required) -def convert_form_field_with_choices(name, field): +def get_form_name(form): + """Get form name""" + class_name = str(form.__class__).split('.')[-1] + return class_name[:-2] + + +def convert_form_field_with_choices(field, name=None, form=None): """ Helper method to convert a field to graphene Field type. :param name: form field's name @@ -96,7 +102,11 @@ def convert_form_field_with_choices(name, field): choices = getattr(field, 'choices', None) if choices: - name = to_camel_case(field.label or name) + if form: + name = to_camel_case("{}_{}".format(get_form_name(form), field.label or name)) + else: + name = field.label or name + name = to_camel_case(name.replace(' ', '_')) choices = list(get_choices(choices)) named_choices = [(c[0], c[1]) for c in choices] named_choices_descriptions = {c[0]: c[2] for c in choices} diff --git a/graphene_django/forms/mutation.py b/graphene_django/forms/mutation.py index 0b64c46..4bc3075 100644 --- a/graphene_django/forms/mutation.py +++ b/graphene_django/forms/mutation.py @@ -30,7 +30,7 @@ def fields_for_form(form, only_fields, exclude_fields): if is_not_in_only or is_excluded: continue - fields[name] = convert_form_field_with_choices(name, field) + fields[name] = convert_form_field_with_choices(field, name=name, form=form) return fields From f3660b3f30bd45ff72814a7eea3e63c2e2d688ad Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Sun, 3 Mar 2019 15:34:01 -0500 Subject: [PATCH 5/8] Update tests --- graphene_django/forms/tests/test_converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene_django/forms/tests/test_converter.py b/graphene_django/forms/tests/test_converter.py index 6039eac..e76c5c2 100644 --- a/graphene_django/forms/tests/test_converter.py +++ b/graphene_django/forms/tests/test_converter.py @@ -117,5 +117,5 @@ def test_should_manytoone_convert_connectionorlist(): def test_should_typed_choice_convert_enum(): field = forms.TypedChoiceField(choices=(('A', 'Choice A'), ('B', 'Choice B')), label='field') - graphene_type = convert_form_field_with_choices('field_name', field) + graphene_type = convert_form_field_with_choices(field, name='field_name') assert isinstance(graphene_type, Enum) From 41222c15653996bf420836146c828efaf13d20b1 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Mon, 4 Mar 2019 08:51:21 -0500 Subject: [PATCH 6/8] Fix lint errors --- graphene_django/fields.py | 3 ++- graphene_django/forms/mutation.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/graphene_django/fields.py b/graphene_django/fields.py index e078ba4..e3129c6 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -167,5 +167,6 @@ class DjangoField(Field): """Intercept resolver to analyse permissions""" parent_resolver = super(DjangoField, self).get_resolver(parent_resolver) if self.permissions: - return partial(get_unbound_function(self.permissions_resolver), parent_resolver, self.permissions, None, None, True) + return partial(get_unbound_function(self.permissions_resolver), parent_resolver, self.permissions, None, + None, True) return parent_resolver diff --git a/graphene_django/forms/mutation.py b/graphene_django/forms/mutation.py index 4bc3075..ecf492c 100644 --- a/graphene_django/forms/mutation.py +++ b/graphene_django/forms/mutation.py @@ -13,7 +13,7 @@ from graphene.types.mutation import MutationOptions from graphene.types.utils import yank_fields_from_attrs from graphene_django.registry import get_global_registry -from .converter import convert_form_field, convert_form_field_with_choices +from .converter import convert_form_field_with_choices from .types import ErrorType From 4996a7272502d0fd283cd74a0ec535eb1c96d852 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Mon, 4 Mar 2019 08:52:59 -0500 Subject: [PATCH 7/8] Set model dependency in conversion --- graphene_django/forms/converter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graphene_django/forms/converter.py b/graphene_django/forms/converter.py index bbaba98..09771b6 100644 --- a/graphene_django/forms/converter.py +++ b/graphene_django/forms/converter.py @@ -101,7 +101,8 @@ def convert_form_field_with_choices(field, name=None, form=None): """ choices = getattr(field, 'choices', None) - if choices: + # If is a choice field, but not depends on models + if choices and not isinstance(form, (forms.ModelMultipleChoiceField, forms.ModelChoiceField)): if form: name = to_camel_case("{}_{}".format(get_form_name(form), field.label or name)) else: From b93bbb9546a0fdf51a07b1ad2e7585e1487f5c81 Mon Sep 17 00:00:00 2001 From: Olivia Rodriguez Valdes Date: Mon, 4 Mar 2019 09:03:52 -0500 Subject: [PATCH 8/8] Add form param to comments --- graphene_django/forms/converter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graphene_django/forms/converter.py b/graphene_django/forms/converter.py index 09771b6..6b17f6b 100644 --- a/graphene_django/forms/converter.py +++ b/graphene_django/forms/converter.py @@ -97,12 +97,13 @@ def convert_form_field_with_choices(field, name=None, form=None): Helper method to convert a field to graphene Field type. :param name: form field's name :param field: form field to convert to + :param form: field's form :return: graphene Field """ choices = getattr(field, 'choices', None) # If is a choice field, but not depends on models - if choices and not isinstance(form, (forms.ModelMultipleChoiceField, forms.ModelChoiceField)): + if choices and not isinstance(field, (forms.ModelMultipleChoiceField, forms.ModelChoiceField)): if form: name = to_camel_case("{}_{}".format(get_form_name(form), field.label or name)) else: