Skip to content

Commit 7f96500

Browse files
committed
Added support for converting Postgres fields
1 parent a1dd2b6 commit 7f96500

File tree

4 files changed

+59
-8
lines changed

4 files changed

+59
-8
lines changed

graphene/contrib/django/compat.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
from django.db import models
22

3+
4+
class MissingType(object):
5+
pass
6+
37
try:
48
UUIDField = models.UUIDField
59
except AttributeError:
610
# Improved compatibility for Django 1.6
7-
class UUIDField(object):
8-
pass
11+
UUIDField = MissingType
912

1013
try:
1114
from django.db.models.related import RelatedObject
1215
except:
1316
# Improved compatibility for Django 1.6
14-
class RelatedObject(object):
15-
pass
17+
RelatedObject = MissingType
18+
19+
20+
try:
21+
# Postgres fields are only available in Django 1.8+
22+
from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField
23+
except ImportError:
24+
ArrayField, HStoreField, JSONField = (MissingType, ) * 3

graphene/contrib/django/converter.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from django.db import models
22

3+
from ...core.types.definitions import List
34
from ...core.types.scalars import ID, Boolean, Float, Int, String
45
from ...core.classtypes.enum import Enum
5-
from .compat import RelatedObject, UUIDField
6+
from .compat import RelatedObject, UUIDField, ArrayField, HStoreField, JSONField
67
from .utils import get_related_model, import_single_dispatch
78

89
singledispatch = import_single_dispatch()
@@ -33,6 +34,8 @@ def convert_django_field(field):
3334
@convert_django_field.register(models.GenericIPAddressField)
3435
@convert_django_field.register(models.FileField)
3536
@convert_django_field.register(UUIDField)
37+
@convert_django_field.register(HStoreField)
38+
@convert_django_field.register(JSONField)
3639
def convert_field_to_string(field):
3740
return String(description=field.help_text)
3841

@@ -89,3 +92,9 @@ def convert_relatedfield_to_djangomodel(field):
8992
def convert_field_to_djangomodel(field):
9093
from .fields import DjangoModelField
9194
return DjangoModelField(get_related_model(field), description=field.help_text)
95+
96+
97+
@convert_django_field.register(ArrayField)
98+
def convert_field_to_list(field):
99+
base_type = convert_django_field(field.base_field)
100+
return List(base_type, description=field.help_text)

graphene/contrib/django/tests/test_converter.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import pytest
12
from django.db import models
23
from py.test import raises
34

45
import graphene
5-
from graphene.contrib.django.converter import (
6+
from ..converter import (
67
convert_django_field, convert_django_field_with_choices)
7-
from graphene.contrib.django.fields import (ConnectionOrListField,
8-
DjangoModelField)
8+
from ..fields import (ConnectionOrListField,
9+
DjangoModelField)
10+
from ..compat import MissingType, ArrayField, HStoreField, JSONField
911

1012
from .models import Article, Reporter
1113

@@ -144,3 +146,32 @@ def test_should_onetoone_convert_model():
144146
def test_should_foreignkey_convert_model():
145147
field = assert_conversion(models.ForeignKey, DjangoModelField, Article)
146148
assert field.type.model == Article
149+
150+
151+
@pytest.mark.skipif(ArrayField is MissingType,
152+
reason="ArrayField should exist")
153+
def test_should_postgres_array_convert_list():
154+
field = assert_conversion(ArrayField, graphene.List, models.CharField(max_length=100))
155+
assert isinstance(field.type, graphene.List)
156+
assert isinstance(field.type.of_type, graphene.String)
157+
158+
159+
@pytest.mark.skipif(ArrayField is MissingType,
160+
reason="ArrayField should exist")
161+
def test_should_postgres_array_multiple_convert_list():
162+
field = assert_conversion(ArrayField, graphene.List, ArrayField(models.CharField(max_length=100)))
163+
assert isinstance(field.type, graphene.List)
164+
assert isinstance(field.type.of_type, graphene.List)
165+
assert isinstance(field.type.of_type.of_type, graphene.String)
166+
167+
168+
@pytest.mark.skipif(HStoreField is MissingType,
169+
reason="HStoreField should exist")
170+
def test_should_postgres_hstore_convert_string():
171+
assert_conversion(HStoreField, graphene.String)
172+
173+
174+
@pytest.mark.skipif(JSONField is MissingType,
175+
reason="JSONField should exist")
176+
def test_should_postgres_json_convert_string():
177+
assert_conversion(JSONField, graphene.String)

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def run_tests(self):
6565
'sqlalchemy',
6666
'sqlalchemy_utils',
6767
'mock',
68+
# Required for Django postgres fields testing
69+
'psycopg2',
6870
],
6971
extras_require={
7072
'django': [

0 commit comments

Comments
 (0)