From 81560df6a13347f09abad52fdb9266465bb9e1af Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 2 Apr 2016 19:19:40 -0700 Subject: [PATCH] Added JSONString custom scalar --- graphene/contrib/django/converter.py | 5 ++--- .../contrib/django/tests/test_converter.py | 5 +++-- graphene/contrib/django/tests/test_query.py | 22 +++++++++++++++---- graphene/core/types/custom_scalars.py | 21 ++++++++++++++++++ 4 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 graphene/core/types/custom_scalars.py diff --git a/graphene/contrib/django/converter.py b/graphene/contrib/django/converter.py index 454edab3..3546bc9b 100644 --- a/graphene/contrib/django/converter.py +++ b/graphene/contrib/django/converter.py @@ -1,9 +1,8 @@ from django.db import models -from ...core.classtypes.objecttype import ObjectType from ...core.types.definitions import List -from ...core.types.field import Field from ...core.types.scalars import ID, Boolean, Float, Int, String +from ...core.types.custom_scalars import JSONString from ...core.classtypes.enum import Enum from .compat import RelatedObject, UUIDField, ArrayField, HStoreField, JSONField, RangeField from .utils import get_related_model, import_single_dispatch @@ -103,7 +102,7 @@ def convert_postgres_array_to_list(field): @convert_django_field.register(HStoreField) @convert_django_field.register(JSONField) def convert_posgres_field_to_string(field): - return String(description=field.help_text) + return JSONString(description=field.help_text) @convert_django_field.register(RangeField) diff --git a/graphene/contrib/django/tests/test_converter.py b/graphene/contrib/django/tests/test_converter.py index 8628ad12..b84c52f1 100644 --- a/graphene/contrib/django/tests/test_converter.py +++ b/graphene/contrib/django/tests/test_converter.py @@ -8,6 +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 .models import Article, Reporter @@ -168,13 +169,13 @@ def test_should_postgres_array_multiple_convert_list(): @pytest.mark.skipif(HStoreField is MissingType, reason="HStoreField should exist") def test_should_postgres_hstore_convert_string(): - assert_conversion(HStoreField, graphene.String) + assert_conversion(HStoreField, JSONString) @pytest.mark.skipif(JSONField is MissingType, reason="JSONField should exist") def test_should_postgres_json_convert_string(): - assert_conversion(JSONField, graphene.String) + assert_conversion(JSONField, JSONString) @pytest.mark.skipif(RangeField is MissingType, diff --git a/graphene/contrib/django/tests/test_query.py b/graphene/contrib/django/tests/test_query.py index 85cdf103..bf9966bc 100644 --- a/graphene/contrib/django/tests/test_query.py +++ b/graphene/contrib/django/tests/test_query.py @@ -66,11 +66,14 @@ def test_should_query_well(): @pytest.mark.skipif(RangeField is MissingType, reason="RangeField should exist") -def test_should_query_ranges(): - from django.contrib.postgres.fields import IntegerRangeField +def test_should_query_postgres_fields(): + from django.contrib.postgres.fields import IntegerRangeField, ArrayField, JSONField, HStoreField class Event(models.Model): - ages = IntegerRangeField(help_text='Range desc') + ages = IntegerRangeField(help_text='The age ranges') + data = JSONField(help_text='Data') + store = HStoreField() + tags = ArrayField(models.CharField(max_length=50)) class EventType(DjangoObjectType): class Meta: @@ -80,19 +83,30 @@ def test_should_query_ranges(): event = graphene.Field(EventType) def resolve_event(self, *args, **kwargs): - return Event(ages=(0, 10)) + return Event( + ages=(0, 10), + data={'angry_babies': True}, + store={'h': 'store'}, + tags=['child', 'angry', 'babies'] + ) schema = graphene.Schema(query=Query) query = ''' query myQuery { event { ages + tags + data + store } } ''' expected = { 'event': { 'ages': [0, 10], + 'tags': ['child', 'angry', 'babies'], + 'data': '{"angry_babies": true}', + 'store': '{"h": "store"}', }, } result = schema.execute(query) diff --git a/graphene/core/types/custom_scalars.py b/graphene/core/types/custom_scalars.py new file mode 100644 index 00000000..3497011c --- /dev/null +++ b/graphene/core/types/custom_scalars.py @@ -0,0 +1,21 @@ +import json + +from graphql.core.language import ast +from ...core.classtypes.scalar import Scalar + + +class JSONString(Scalar): + '''JSON String''' + + @staticmethod + def serialize(dt): + return json.dumps(dt) + + @staticmethod + def parse_literal(node): + if isinstance(node, ast.StringValue): + return json.dumps(node.value) + + @staticmethod + def parse_value(value): + return json.dumps(value)