Added support for converting Postgres fields

This commit is contained in:
Syrus Akbary 2016-04-02 18:02:13 -07:00
parent a1dd2b6293
commit 7f96500353
4 changed files with 59 additions and 8 deletions

View File

@ -1,15 +1,24 @@
from django.db import models from django.db import models
class MissingType(object):
pass
try: try:
UUIDField = models.UUIDField UUIDField = models.UUIDField
except AttributeError: except AttributeError:
# Improved compatibility for Django 1.6 # Improved compatibility for Django 1.6
class UUIDField(object): UUIDField = MissingType
pass
try: try:
from django.db.models.related import RelatedObject from django.db.models.related import RelatedObject
except: except:
# Improved compatibility for Django 1.6 # Improved compatibility for Django 1.6
class RelatedObject(object): RelatedObject = MissingType
pass
try:
# Postgres fields are only available in Django 1.8+
from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField
except ImportError:
ArrayField, HStoreField, JSONField = (MissingType, ) * 3

View File

@ -1,8 +1,9 @@
from django.db import models from django.db import models
from ...core.types.definitions import List
from ...core.types.scalars import ID, Boolean, Float, Int, String from ...core.types.scalars import ID, Boolean, Float, Int, String
from ...core.classtypes.enum import Enum from ...core.classtypes.enum import Enum
from .compat import RelatedObject, UUIDField from .compat import RelatedObject, UUIDField, ArrayField, HStoreField, JSONField
from .utils import get_related_model, import_single_dispatch from .utils import get_related_model, import_single_dispatch
singledispatch = import_single_dispatch() singledispatch = import_single_dispatch()
@ -33,6 +34,8 @@ def convert_django_field(field):
@convert_django_field.register(models.GenericIPAddressField) @convert_django_field.register(models.GenericIPAddressField)
@convert_django_field.register(models.FileField) @convert_django_field.register(models.FileField)
@convert_django_field.register(UUIDField) @convert_django_field.register(UUIDField)
@convert_django_field.register(HStoreField)
@convert_django_field.register(JSONField)
def convert_field_to_string(field): def convert_field_to_string(field):
return String(description=field.help_text) return String(description=field.help_text)
@ -89,3 +92,9 @@ def convert_relatedfield_to_djangomodel(field):
def convert_field_to_djangomodel(field): def convert_field_to_djangomodel(field):
from .fields import DjangoModelField from .fields import DjangoModelField
return DjangoModelField(get_related_model(field), description=field.help_text) return DjangoModelField(get_related_model(field), description=field.help_text)
@convert_django_field.register(ArrayField)
def convert_field_to_list(field):
base_type = convert_django_field(field.base_field)
return List(base_type, description=field.help_text)

View File

@ -1,11 +1,13 @@
import pytest
from django.db import models from django.db import models
from py.test import raises from py.test import raises
import graphene import graphene
from graphene.contrib.django.converter import ( from ..converter import (
convert_django_field, convert_django_field_with_choices) convert_django_field, convert_django_field_with_choices)
from graphene.contrib.django.fields import (ConnectionOrListField, from ..fields import (ConnectionOrListField,
DjangoModelField) DjangoModelField)
from ..compat import MissingType, ArrayField, HStoreField, JSONField
from .models import Article, Reporter from .models import Article, Reporter
@ -144,3 +146,32 @@ def test_should_onetoone_convert_model():
def test_should_foreignkey_convert_model(): def test_should_foreignkey_convert_model():
field = assert_conversion(models.ForeignKey, DjangoModelField, Article) field = assert_conversion(models.ForeignKey, DjangoModelField, Article)
assert field.type.model == Article assert field.type.model == Article
@pytest.mark.skipif(ArrayField is MissingType,
reason="ArrayField should exist")
def test_should_postgres_array_convert_list():
field = assert_conversion(ArrayField, graphene.List, models.CharField(max_length=100))
assert isinstance(field.type, graphene.List)
assert isinstance(field.type.of_type, graphene.String)
@pytest.mark.skipif(ArrayField is MissingType,
reason="ArrayField should exist")
def test_should_postgres_array_multiple_convert_list():
field = assert_conversion(ArrayField, graphene.List, ArrayField(models.CharField(max_length=100)))
assert isinstance(field.type, graphene.List)
assert isinstance(field.type.of_type, graphene.List)
assert isinstance(field.type.of_type.of_type, graphene.String)
@pytest.mark.skipif(HStoreField is MissingType,
reason="HStoreField should exist")
def test_should_postgres_hstore_convert_string():
assert_conversion(HStoreField, graphene.String)
@pytest.mark.skipif(JSONField is MissingType,
reason="JSONField should exist")
def test_should_postgres_json_convert_string():
assert_conversion(JSONField, graphene.String)

View File

@ -65,6 +65,8 @@ setup(
'sqlalchemy', 'sqlalchemy',
'sqlalchemy_utils', 'sqlalchemy_utils',
'mock', 'mock',
# Required for Django postgres fields testing
'psycopg2',
], ],
extras_require={ extras_require={
'django': [ 'django': [