Introduced optional_fields to SerializationMutation (#1080)

* added optional_field to SerializationMutation to forcefully mark some fields as optional

* added tests
This commit is contained in:
Rustam Ganeyev 2021-01-02 04:36:50 +00:00 committed by GitHub
parent caf9548610
commit 1281c1338d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 4 deletions

View File

@ -18,6 +18,7 @@ class SerializerMutationOptions(MutationOptions):
model_class = None
model_operations = ["create", "update"]
serializer_class = None
optional_fields = ()
def fields_for_serializer(
@ -27,6 +28,7 @@ def fields_for_serializer(
is_input=False,
convert_choices_to_enum=True,
lookup_field=None,
optional_fields=(),
):
fields = OrderedDict()
for name, field in serializer.fields.items():
@ -44,9 +46,13 @@ def fields_for_serializer(
if is_not_in_only or is_excluded:
continue
is_optional = name in optional_fields
fields[name] = convert_serializer_field(
field, is_input=is_input, convert_choices_to_enum=convert_choices_to_enum
field,
is_input=is_input,
convert_choices_to_enum=convert_choices_to_enum,
force_optional=is_optional,
)
return fields
@ -70,6 +76,7 @@ class SerializerMutation(ClientIDMutation):
exclude_fields=(),
convert_choices_to_enum=True,
_meta=None,
optional_fields=(),
**options
):
@ -95,6 +102,7 @@ class SerializerMutation(ClientIDMutation):
is_input=True,
convert_choices_to_enum=convert_choices_to_enum,
lookup_field=lookup_field,
optional_fields=optional_fields,
)
output_fields = fields_for_serializer(
serializer,

View File

@ -19,7 +19,9 @@ def get_graphene_type_from_serializer_field(field):
)
def convert_serializer_field(field, is_input=True, convert_choices_to_enum=True):
def convert_serializer_field(
field, is_input=True, convert_choices_to_enum=True, force_optional=False
):
"""
Converts a django rest frameworks field to a graphql field
and marks the field as required if we are creating an input type
@ -32,7 +34,10 @@ def convert_serializer_field(field, is_input=True, convert_choices_to_enum=True)
graphql_type = get_graphene_type_from_serializer_field(field)
args = []
kwargs = {"description": field.help_text, "required": is_input and field.required}
kwargs = {
"description": field.help_text,
"required": is_input and field.required and not force_optional,
}
# if it is a tuple or a list it means that we are returning
# the graphql type and the child type

View File

@ -3,7 +3,7 @@ import datetime
from py.test import raises
from rest_framework import serializers
from graphene import Field, ResolveInfo
from graphene import Field, ResolveInfo, NonNull, String
from graphene.types.inputobjecttype import InputObjectType
from ...types import DjangoObjectType
@ -98,6 +98,25 @@ def test_exclude_fields():
assert "created" not in MyMutation.Input._meta.fields
def test_model_serializer_required_fields():
class MyMutation(SerializerMutation):
class Meta:
serializer_class = MyModelSerializer
assert "cool_name" in MyMutation.Input._meta.fields
assert MyMutation.Input._meta.fields["cool_name"].type == NonNull(String)
def test_model_serializer_optional_fields():
class MyMutation(SerializerMutation):
class Meta:
serializer_class = MyModelSerializer
optional_fields = ("cool_name",)
assert "cool_name" in MyMutation.Input._meta.fields
assert MyMutation.Input._meta.fields["cool_name"].type == String
def test_write_only_field():
class WriteOnlyFieldModelSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)