diff --git a/graphene_django/rest_framework/mutation.py b/graphene_django/rest_framework/mutation.py index beaaa493f..94d1e4b81 100644 --- a/graphene_django/rest_framework/mutation.py +++ b/graphene_django/rest_framework/mutation.py @@ -55,6 +55,7 @@ def __init_subclass_with_meta__(cls, serializer_class=None, output_fields = fields_for_serializer(serializer, only_fields, exclude_fields, is_input=False) _meta = SerializerMutationOptions(cls) + _meta.serializer_class = serializer_class _meta.fields = yank_fields_from_attrs( output_fields, _as=Field, @@ -83,4 +84,4 @@ def mutate_and_get_payload(cls, root, info, **input): @classmethod def perform_mutate(cls, serializer, info): obj = serializer.save() - return cls(**obj) + return cls(errors=None, **obj) diff --git a/graphene_django/rest_framework/serializer_converter.py b/graphene_django/rest_framework/serializer_converter.py index e115e82c4..c472cee9c 100644 --- a/graphene_django/rest_framework/serializer_converter.py +++ b/graphene_django/rest_framework/serializer_converter.py @@ -42,8 +42,7 @@ def convert_serializer_field(field, is_input=True): if isinstance(field, serializers.ModelSerializer): if is_input: - return Dynamic(lambda: None) - # graphql_type = convert_serializer_to_input_type(field.__class__) + graphql_type = convert_serializer_to_input_type(field.__class__) else: global_registry = get_global_registry() field_model = field.Meta.model @@ -52,6 +51,21 @@ def convert_serializer_field(field, is_input=True): return graphql_type(*args, **kwargs) +def convert_serializer_to_input_type(serializer_class): + serializer = serializer_class() + + items = { + name: convert_serializer_field(field) + for name, field in serializer.fields.items() + } + + return type( + '{}Input'.format(serializer.__class__.__name__), + (graphene.InputObjectType,), + items + ) + + @get_graphene_type_from_serializer_field.register(serializers.Field) def convert_serializer_field_to_string(field): return graphene.String diff --git a/graphene_django/rest_framework/tests/test_mutation.py b/graphene_django/rest_framework/tests/test_mutation.py index 836f3fe15..852265d83 100644 --- a/graphene_django/rest_framework/tests/test_mutation.py +++ b/graphene_django/rest_framework/tests/test_mutation.py @@ -22,6 +22,9 @@ class MySerializer(serializers.Serializer): text = serializers.CharField() model = MyModelSerializer() + def create(self, validated_data): + return validated_data + def test_needs_serializer_class(): with raises(Exception) as exc: @@ -65,7 +68,32 @@ class Meta: assert model_field.type == MyFakeModelGrapheneType model_input = MyMutation.Input._meta.fields['model'] - model_input_type = model_input.get_type() - assert not model_input_type - # assert issubclass(model_input_type, InputObjectType) - # assert 'cool_name' in model_input_type._meta.fields + model_input_type = model_input._type.of_type + assert issubclass(model_input_type, InputObjectType) + assert 'cool_name' in model_input_type._meta.fields + + +def test_mutate_and_get_payload_success(): + + class MyMutation(SerializerMutation): + class Meta: + serializer_class = MySerializer + + result = MyMutation.mutate_and_get_payload(None, None, **{ + 'text': 'value', + 'model': { + 'cool_name': 'other_value' + } + }) + assert result.errors is None + + +def test_mutate_and_get_payload_error(): + + class MyMutation(SerializerMutation): + class Meta: + serializer_class = MySerializer + + # missing required fields + result = MyMutation.mutate_and_get_payload(None, None, **{}) + assert len(result.errors) > 0 \ No newline at end of file