Skip to content

Commit 42e9107

Browse files
authored
Merge pull request #1 from spockNinja/feature/rest-framework
Account for nested models and Dates/Times
2 parents 93bbc19 + afbe6c9 commit 42e9107

File tree

3 files changed

+86
-15
lines changed

3 files changed

+86
-15
lines changed

graphene_django/rest_framework/serializer_converter.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import graphene
55

6+
from ..registry import get_global_registry
67
from ..utils import import_single_dispatch
78
from .types import DictType
89

@@ -41,6 +42,7 @@ def convert_serializer_field(field, is_input=True):
4142

4243
graphql_type = get_graphene_type_from_serializer_field(field)
4344

45+
args = []
4446
kwargs = {
4547
'description': field.help_text,
4648
'required': is_input and field.required,
@@ -52,14 +54,27 @@ def convert_serializer_field(field, is_input=True):
5254
kwargs['of_type'] = graphql_type[1]
5355
graphql_type = graphql_type[0]
5456

55-
return graphql_type(**kwargs)
57+
if isinstance(field, serializers.ModelSerializer):
58+
if is_input:
59+
graphql_type = convert_serializer_to_input_type(field.__class__)
60+
else:
61+
global_registry = get_global_registry()
62+
field_model = field.Meta.model
63+
args = [global_registry.get_type_for_model(field_model)]
64+
65+
return graphql_type(*args, **kwargs)
5666

5767

5868
@get_graphene_type_from_serializer_field.register(serializers.Field)
5969
def convert_serializer_field_to_string(field):
6070
return graphene.String
6171

6272

73+
@get_graphene_type_from_serializer_field.register(serializers.ModelSerializer)
74+
def convert_serializer_to_field(field):
75+
return graphene.Field
76+
77+
6378
@get_graphene_type_from_serializer_field.register(serializers.IntegerField)
6479
def convert_serializer_field_to_int(field):
6580
return graphene.Int
@@ -76,6 +91,17 @@ def convert_serializer_field_to_float(field):
7691
return graphene.Float
7792

7893

94+
@get_graphene_type_from_serializer_field.register(serializers.DateTimeField)
95+
@get_graphene_type_from_serializer_field.register(serializers.DateField)
96+
def convert_serializer_field_to_date_time(field):
97+
return graphene.types.datetime.DateTime
98+
99+
100+
@get_graphene_type_from_serializer_field.register(serializers.TimeField)
101+
def convert_serializer_field_to_time(field):
102+
return graphene.types.datetime.Time
103+
104+
79105
@get_graphene_type_from_serializer_field.register(serializers.ListField)
80106
def convert_serializer_field_to_list(field, is_input=True):
81107
child_type = get_graphene_type_from_serializer_field(field.child)

graphene_django/rest_framework/tests/test_field_converter.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ..types import DictType
99

1010

11-
def _get_type(rest_framework_field, **kwargs):
11+
def _get_type(rest_framework_field, is_input=True, **kwargs):
1212
# prevents the following error:
1313
# AssertionError: The `source` argument is not meaningful when applied to a `child=` field.
1414
# Remove `source=` from the field declaration.
@@ -19,7 +19,7 @@ def _get_type(rest_framework_field, **kwargs):
1919

2020
field = rest_framework_field(**kwargs)
2121

22-
return convert_serializer_field(field)
22+
return convert_serializer_field(field, is_input=is_input)
2323

2424

2525
def assert_conversion(rest_framework_field, graphene_field, **kwargs):
@@ -40,18 +40,6 @@ def test_should_unknown_rest_framework_field_raise_exception():
4040
assert 'Don\'t know how to convert the serializer field' in str(excinfo.value)
4141

4242

43-
def test_should_date_convert_string():
44-
assert_conversion(serializers.DateField, graphene.String)
45-
46-
47-
def test_should_time_convert_string():
48-
assert_conversion(serializers.TimeField, graphene.String)
49-
50-
51-
def test_should_date_time_convert_string():
52-
assert_conversion(serializers.DateTimeField, graphene.String)
53-
54-
5543
def test_should_char_convert_string():
5644
assert_conversion(serializers.CharField, graphene.String)
5745

@@ -85,6 +73,28 @@ def test_should_uuid_convert_string():
8573
assert_conversion(serializers.UUIDField, graphene.String)
8674

8775

76+
def test_should_model_convert_field():
77+
78+
class MyModelSerializer(serializers.ModelSerializer):
79+
class Meta:
80+
model = None
81+
fields = '__all__'
82+
83+
assert_conversion(MyModelSerializer, graphene.Field, is_input=False)
84+
85+
86+
def test_should_date_time_convert_datetime():
87+
assert_conversion(serializers.DateTimeField, graphene.types.datetime.DateTime)
88+
89+
90+
def test_should_date_convert_datetime():
91+
assert_conversion(serializers.DateField, graphene.types.datetime.DateTime)
92+
93+
94+
def test_should_time_convert_time():
95+
assert_conversion(serializers.TimeField, graphene.types.datetime.Time)
96+
97+
8898
def test_should_integer_convert_int():
8999
assert_conversion(serializers.IntegerField, graphene.Int)
90100

graphene_django/rest_framework/tests/test_mutation.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1+
from django.db import models
2+
from graphene import Field
3+
from graphene.types.inputobjecttype import InputObjectType
14
from py.test import raises
25
from rest_framework import serializers
36

7+
from ...types import DjangoObjectType
48
from ..mutation import SerializerMutation
59

610

11+
class MyFakeModel(models.Model):
12+
cool_name = models.CharField(max_length=50)
13+
14+
15+
class MyModelSerializer(serializers.ModelSerializer):
16+
class Meta:
17+
model = MyFakeModel
18+
fields = '__all__'
19+
20+
721
class MySerializer(serializers.Serializer):
822
text = serializers.CharField()
23+
model = MyModelSerializer()
924

1025

1126
def test_needs_serializer_class():
@@ -22,6 +37,7 @@ class Meta:
2237
serializer_class = MySerializer
2338

2439
assert 'text' in MyMutation._meta.fields
40+
assert 'model' in MyMutation._meta.fields
2541
assert 'errors' in MyMutation._meta.fields
2642

2743

@@ -31,5 +47,24 @@ class Meta:
3147
serializer_class = MySerializer
3248

3349
assert 'text' in MyMutation.Input._meta.fields
50+
assert 'model' in MyMutation.Input._meta.fields
51+
52+
53+
def test_nested_model():
54+
55+
class MyFakeModelGrapheneType(DjangoObjectType):
56+
class Meta:
57+
model = MyFakeModel
58+
59+
class MyMutation(SerializerMutation):
60+
class Meta:
61+
serializer_class = MySerializer
3462

63+
model_field = MyMutation._meta.fields['model']
64+
assert isinstance(model_field, Field)
65+
assert model_field.type == MyFakeModelGrapheneType
3566

67+
model_input = MyMutation.Input._meta.fields['model']
68+
model_input_type = model_input._type.of_type
69+
assert issubclass(model_input_type, InputObjectType)
70+
assert 'cool_name' in model_input_type._meta.fields

0 commit comments

Comments
 (0)