Skip to content

Commit 6a19ab5

Browse files
authored
use to_representation in favor of get_attribute (#848)
* use `to_represenation` in favor of `get_attribute` * fix datetime type does get converted to a string to_representation will convert the datetime field into a string representation. However the to_representation on the method field will only call its underlying method. * fix add missing import * apply black formatter * add test for serializer method field * apply black format * improve backward compatibility by using date's class contructor instead of fromisostring * apply black format * fix black format issue
1 parent d1a9444 commit 6a19ab5

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

graphene_django/rest_framework/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ class MyFakeModel(models.Model):
99
class MyFakeModelWithPassword(models.Model):
1010
cool_name = models.CharField(max_length=50)
1111
password = models.CharField(max_length=50)
12+
13+
14+
class MyFakeModelWithDate(models.Model):
15+
cool_name = models.CharField(max_length=50)
16+
last_edited = models.DateField()

graphene_django/rest_framework/mutation.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from collections import OrderedDict
22

33
from django.shortcuts import get_object_or_404
4+
from rest_framework import serializers
45

56
import graphene
67
from graphene.relay.mutation import ClientIDMutation
@@ -158,6 +159,9 @@ def perform_mutate(cls, serializer, info):
158159
kwargs = {}
159160
for f, field in serializer.fields.items():
160161
if not field.write_only:
161-
kwargs[f] = field.get_attribute(obj)
162+
if isinstance(field, serializers.SerializerMethodField):
163+
kwargs[f] = field.to_representation(obj)
164+
else:
165+
kwargs[f] = field.get_attribute(obj)
162166

163167
return cls(errors=None, **kwargs)

graphene_django/rest_framework/tests/test_mutation.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from ...settings import graphene_settings
1010
from ...types import DjangoObjectType
11-
from ..models import MyFakeModel, MyFakeModelWithPassword
11+
from ..models import MyFakeModel, MyFakeModelWithPassword, MyFakeModelWithDate
1212
from ..mutation import SerializerMutation
1313

1414

@@ -33,6 +33,18 @@ class Meta:
3333
fields = "__all__"
3434

3535

36+
class MyModelSerializerWithMethod(serializers.ModelSerializer):
37+
days_since_last_edit = serializers.SerializerMethodField()
38+
39+
class Meta:
40+
model = MyFakeModelWithDate
41+
fields = "__all__"
42+
43+
def get_days_since_last_edit(self, obj):
44+
now = datetime.date(2020, 1, 8)
45+
return (now - obj.last_edited).days
46+
47+
3648
class MyModelMutation(SerializerMutation):
3749
class Meta:
3850
serializer_class = MyModelSerializer
@@ -208,6 +220,23 @@ class Meta:
208220
assert '"id" required' in str(exc.value)
209221

210222

223+
@mark.django_db
224+
def test_perform_mutate_success():
225+
class MyMethodMutation(SerializerMutation):
226+
class Meta:
227+
serializer_class = MyModelSerializerWithMethod
228+
229+
result = MyMethodMutation.mutate_and_get_payload(
230+
None,
231+
mock_info(),
232+
**{"cool_name": "Narf", "last_edited": datetime.date(2020, 1, 4)}
233+
)
234+
235+
assert result.errors is None
236+
assert result.cool_name == "Narf"
237+
assert result.days_since_last_edit == 4
238+
239+
211240
def test_mutate_and_get_payload_error():
212241
class MyMutation(SerializerMutation):
213242
class Meta:

0 commit comments

Comments
 (0)