diff --git a/graphene_django/rest_framework/models.py b/graphene_django/rest_framework/models.py index 06d9b60..bd84ce5 100644 --- a/graphene_django/rest_framework/models.py +++ b/graphene_django/rest_framework/models.py @@ -9,3 +9,8 @@ class MyFakeModel(models.Model): class MyFakeModelWithPassword(models.Model): cool_name = models.CharField(max_length=50) password = models.CharField(max_length=50) + + +class MyFakeModelWithDate(models.Model): + cool_name = models.CharField(max_length=50) + last_edited = models.DateField() diff --git a/graphene_django/rest_framework/mutation.py b/graphene_django/rest_framework/mutation.py index cba6b47..1365b5c 100644 --- a/graphene_django/rest_framework/mutation.py +++ b/graphene_django/rest_framework/mutation.py @@ -1,6 +1,7 @@ from collections import OrderedDict from django.shortcuts import get_object_or_404 +from rest_framework import serializers import graphene from graphene.relay.mutation import ClientIDMutation @@ -158,6 +159,9 @@ class SerializerMutation(ClientIDMutation): kwargs = {} for f, field in serializer.fields.items(): if not field.write_only: - kwargs[f] = field.get_attribute(obj) + if isinstance(field, serializers.SerializerMethodField): + kwargs[f] = field.to_representation(obj) + else: + kwargs[f] = field.get_attribute(obj) return cls(errors=None, **kwargs) diff --git a/graphene_django/rest_framework/tests/test_mutation.py b/graphene_django/rest_framework/tests/test_mutation.py index bfb247d..32f1e28 100644 --- a/graphene_django/rest_framework/tests/test_mutation.py +++ b/graphene_django/rest_framework/tests/test_mutation.py @@ -8,7 +8,7 @@ from graphene.types.inputobjecttype import InputObjectType from ...settings import graphene_settings from ...types import DjangoObjectType -from ..models import MyFakeModel, MyFakeModelWithPassword +from ..models import MyFakeModel, MyFakeModelWithPassword, MyFakeModelWithDate from ..mutation import SerializerMutation @@ -33,6 +33,18 @@ class MyModelSerializer(serializers.ModelSerializer): fields = "__all__" +class MyModelSerializerWithMethod(serializers.ModelSerializer): + days_since_last_edit = serializers.SerializerMethodField() + + class Meta: + model = MyFakeModelWithDate + fields = "__all__" + + def get_days_since_last_edit(self, obj): + now = datetime.date(2020, 1, 8) + return (now - obj.last_edited).days + + class MyModelMutation(SerializerMutation): class Meta: serializer_class = MyModelSerializer @@ -208,6 +220,23 @@ def test_model_invalid_update_mutate_and_get_payload_success(): assert '"id" required' in str(exc.value) +@mark.django_db +def test_perform_mutate_success(): + class MyMethodMutation(SerializerMutation): + class Meta: + serializer_class = MyModelSerializerWithMethod + + result = MyMethodMutation.mutate_and_get_payload( + None, + mock_info(), + **{"cool_name": "Narf", "last_edited": datetime.date(2020, 1, 4)} + ) + + assert result.errors is None + assert result.cool_name == "Narf" + assert result.days_since_last_edit == 4 + + def test_mutate_and_get_payload_error(): class MyMutation(SerializerMutation): class Meta: