From 98a9c7161d1842b41f69429021bce2e50092332d Mon Sep 17 00:00:00 2001 From: Patrick Arminio Date: Sun, 28 Oct 2018 19:40:44 +0000 Subject: [PATCH] Type errors for serializer mutation --- graphene_django/rest_framework/mutation.py | 25 +++++++++++++++---- .../rest_framework/tests/test_mutation.py | 20 ++++++++++++++- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/graphene_django/rest_framework/mutation.py b/graphene_django/rest_framework/mutation.py index 5e343aa..0a88ec2 100644 --- a/graphene_django/rest_framework/mutation.py +++ b/graphene_django/rest_framework/mutation.py @@ -40,10 +40,6 @@ class SerializerMutation(ClientIDMutation): class Meta: abstract = True - errors = graphene.List( - ErrorType, description="May contain more than one error for same field." - ) - @classmethod def __init_subclass_with_meta__( cls, @@ -55,7 +51,6 @@ class SerializerMutation(ClientIDMutation): exclude_fields=(), **options ): - if not serializer_class: raise Exception("serializer_class is required for the SerializerMutation") @@ -78,6 +73,26 @@ class SerializerMutation(ClientIDMutation): serializer, only_fields, exclude_fields, is_input=False ) + error_fields = { + key: graphene.List(graphene.NonNull(graphene.String)) + for key in input_fields.keys() + } + + # TODO: from settings + error_fields['non_field_errors'] = graphene.List( + graphene.NonNull(graphene.String) + ) + + base_name = cls.__name__ + + cls.Errors = type( + "{}Errors".format(base_name), + (graphene.ObjectType, ), + yank_fields_from_attrs(error_fields, _as=Field), + ) + + output_fields['errors'] = graphene.Field(cls.Errors, required=True) + _meta = SerializerMutationOptions(cls) _meta.lookup_field = lookup_field _meta.model_operations = model_operations diff --git a/graphene_django/rest_framework/tests/test_mutation.py b/graphene_django/rest_framework/tests/test_mutation.py index 4dccc18..5afe3cc 100644 --- a/graphene_django/rest_framework/tests/test_mutation.py +++ b/graphene_django/rest_framework/tests/test_mutation.py @@ -1,6 +1,6 @@ import datetime -from graphene import Field, ResolveInfo +from graphene import Field, ResolveInfo, NonNull, List, String from graphene.types.inputobjecttype import InputObjectType from py.test import raises from py.test import mark @@ -177,3 +177,21 @@ def test_invalid_serializer_operations(): model_operations = ["Add"] assert "model_operations" in str(exc.value) + + +def test_errors_field(): + class MyMutation(SerializerMutation): + class Meta: + serializer_class = MySerializer + + errors_field = MyMutation._meta.fields['errors'] + + assert MyMutation.Errors + + assert type(errors_field.type) == NonNull + + errors_field = errors_field.type.of_type + + assert type(errors_field.model.type) == List + assert type(errors_field.model.type.of_type) == NonNull + # TODO: how to test that the nonnull type is a string?