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
This commit is contained in:
B4rtware 2020-02-21 18:42:47 +01:00 committed by GitHub
parent d1a9444401
commit 6a19ab5a4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 2 deletions

View File

@ -9,3 +9,8 @@ class MyFakeModel(models.Model):
class MyFakeModelWithPassword(models.Model): class MyFakeModelWithPassword(models.Model):
cool_name = models.CharField(max_length=50) cool_name = models.CharField(max_length=50)
password = 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()

View File

@ -1,6 +1,7 @@
from collections import OrderedDict from collections import OrderedDict
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from rest_framework import serializers
import graphene import graphene
from graphene.relay.mutation import ClientIDMutation from graphene.relay.mutation import ClientIDMutation
@ -158,6 +159,9 @@ class SerializerMutation(ClientIDMutation):
kwargs = {} kwargs = {}
for f, field in serializer.fields.items(): for f, field in serializer.fields.items():
if not field.write_only: 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) return cls(errors=None, **kwargs)

View File

@ -8,7 +8,7 @@ from graphene.types.inputobjecttype import InputObjectType
from ...settings import graphene_settings from ...settings import graphene_settings
from ...types import DjangoObjectType from ...types import DjangoObjectType
from ..models import MyFakeModel, MyFakeModelWithPassword from ..models import MyFakeModel, MyFakeModelWithPassword, MyFakeModelWithDate
from ..mutation import SerializerMutation from ..mutation import SerializerMutation
@ -33,6 +33,18 @@ class MyModelSerializer(serializers.ModelSerializer):
fields = "__all__" 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 MyModelMutation(SerializerMutation):
class Meta: class Meta:
serializer_class = MyModelSerializer serializer_class = MyModelSerializer
@ -208,6 +220,23 @@ def test_model_invalid_update_mutate_and_get_payload_success():
assert '"id" required' in str(exc.value) 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(): def test_mutate_and_get_payload_error():
class MyMutation(SerializerMutation): class MyMutation(SerializerMutation):
class Meta: class Meta: