diff --git a/graphene/contrib/django/converter.py b/graphene/contrib/django/converter.py index 3546bc9b..e9e633f2 100644 --- a/graphene/contrib/django/converter.py +++ b/graphene/contrib/django/converter.py @@ -2,7 +2,7 @@ from django.db import models from ...core.types.definitions import List from ...core.types.scalars import ID, Boolean, Float, Int, String -from ...core.types.custom_scalars import JSONString +from ...core.types.custom_scalars import JSONString, DateTime from ...core.classtypes.enum import Enum from .compat import RelatedObject, UUIDField, ArrayField, HStoreField, JSONField, RangeField from .utils import get_related_model, import_single_dispatch @@ -26,7 +26,6 @@ def convert_django_field(field): (field, field.__class__)) -@convert_django_field.register(models.DateField) @convert_django_field.register(models.CharField) @convert_django_field.register(models.TextField) @convert_django_field.register(models.EmailField) @@ -69,6 +68,11 @@ def convert_field_to_float(field): return Float(description=field.help_text) +@convert_django_field.register(models.DateField) +def convert_date_to_string(field): + return DateTime(description=field.help_text) + + @convert_django_field.register(models.ManyToManyField) @convert_django_field.register(models.ManyToOneRel) @convert_django_field.register(models.ManyToManyRel) diff --git a/graphene/contrib/django/tests/test_converter.py b/graphene/contrib/django/tests/test_converter.py index b84c52f1..94b4bfff 100644 --- a/graphene/contrib/django/tests/test_converter.py +++ b/graphene/contrib/django/tests/test_converter.py @@ -8,7 +8,7 @@ from ..converter import ( from ..fields import (ConnectionOrListField, DjangoModelField) from ..compat import MissingType, ArrayField, HStoreField, JSONField, RangeField -from graphene.core.types.custom_scalars import JSONString +from graphene.core.types.custom_scalars import JSONString, DateTime from .models import Article, Reporter @@ -29,7 +29,7 @@ def test_should_unknown_django_field_raise_exception(): def test_should_date_convert_string(): - assert_conversion(models.DateField, graphene.String) + assert_conversion(models.DateField, DateTime) def test_should_char_convert_string(): diff --git a/graphene/contrib/django/tests/test_query.py b/graphene/contrib/django/tests/test_query.py index bf9966bc..0a5ffde1 100644 --- a/graphene/contrib/django/tests/test_query.py +++ b/graphene/contrib/django/tests/test_query.py @@ -1,3 +1,4 @@ +import datetime import pytest from py.test import raises from django.db import models @@ -134,7 +135,7 @@ def test_should_node(): @classmethod def get_node(cls, id, info): - return ArticleNode(Article(id=1, headline='Article node')) + return ArticleNode(Article(id=1, headline='Article node', pub_date=datetime.date(2002, 3, 11))) class Query(graphene.ObjectType): node = relay.NodeField() @@ -167,6 +168,7 @@ def test_should_node(): } ... on ArticleNode { headline + pubDate } } } @@ -187,7 +189,8 @@ def test_should_node(): }, 'myArticle': { 'id': 'QXJ0aWNsZU5vZGU6MQ==', - 'headline': 'Article node' + 'headline': 'Article node', + 'pubDate': '2002-03-11', } } schema = graphene.Schema(query=Query) diff --git a/graphene/core/types/custom_scalars.py b/graphene/core/types/custom_scalars.py index 3497011c..e2f0da84 100644 --- a/graphene/core/types/custom_scalars.py +++ b/graphene/core/types/custom_scalars.py @@ -1,4 +1,5 @@ import json +import datetime from graphql.core.language import ast from ...core.classtypes.scalar import Scalar @@ -19,3 +20,21 @@ class JSONString(Scalar): @staticmethod def parse_value(value): return json.dumps(value) + + +class DateTime(Scalar): + '''DateTime in ISO 8601 format''' + + @staticmethod + def serialize(dt): + return dt.isoformat() + + @staticmethod + def parse_literal(node): + if isinstance(node, ast.StringValue): + return datetime.datetime.strptime( + node.value, "%Y-%m-%dT%H:%M:%S.%f") + + @staticmethod + def parse_value(value): + return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")