Skip to content

Commit 1b39992

Browse files
committed
Merge branch 'refs/heads/master' into features/django-fields
Conflicts: graphene/contrib/django/converter.py graphene/core/classtypes/enum.py
2 parents ef1339a + ae23a11 commit 1b39992

File tree

10 files changed

+46
-12
lines changed

10 files changed

+46
-12
lines changed

docs/pages/docs/introspection-schema.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ Graphene comes with a management command for Django to dump your schema data to
1414

1515
## Usage
1616

17-
Include `graphene.django.contrib` to `INSTALLED_APPS` in you project settings:
17+
Include `graphene.contrib.django` to `INSTALLED_APPS` in you project settings:
1818

1919
```python
20-
INSTALLED_APPS += ('graphene.django.contrib')
20+
INSTALLED_APPS += ('graphene.contrib.django')
2121
```
2222

2323
Assuming your Graphene schema is at `tutorial.quickstart.schema`, run the command:

graphene/contrib/django/converter.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,25 @@
44
from ...core.types.custom_scalars import DateTime, JSONString
55
from ...core.types.definitions import List
66
from ...core.types.scalars import ID, Boolean, Float, Int, String
7+
from ...utils import to_const
78
from .compat import (ArrayField, HStoreField, JSONField, RangeField,
89
RelatedObject, UUIDField)
910
from .utils import get_related_model, import_single_dispatch
1011

1112
singledispatch = import_single_dispatch()
1213

1314

15+
def convert_choices(choices):
16+
for value, name in choices:
17+
yield to_const(name), value
18+
19+
1420
def convert_django_field_with_choices(field):
1521
choices = getattr(field, 'choices', None)
1622
if choices:
1723
meta = field.model._meta
1824
name = '{}_{}_{}'.format(meta.app_label, meta.object_name, field.name)
19-
return Enum(name.upper(), choices, description=field.help_text)
25+
return Enum(name.upper(), list(convert_choices(choices)), description=field.help_text)
2026
return convert_django_field(field)
2127

2228

graphene/contrib/django/tests/models.py

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class Article(models.Model):
3030
('es', 'Spanish'),
3131
('en', 'English')
3232
], default='es')
33+
importance = models.IntegerField('Importance', null=True, blank=True,
34+
choices=[(1, u'Very important'), (2, u'Not as important')])
3335

3436
def __str__(self): # __unicode__ on Python 2
3537
return self.headline

graphene/contrib/django/tests/test_converter.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ class Meta:
113113
assert issubclass(graphene_type, graphene.Enum)
114114
assert graphene_type._meta.type_name == 'TEST_TRANSLATEDMODEL_LANGUAGE'
115115
assert graphene_type._meta.description == 'Language'
116-
assert graphene_type.__enum__.__members__['es'].value == 'Spanish'
117-
assert graphene_type.__enum__.__members__['en'].value == 'English'
116+
assert graphene_type.__enum__.__members__['SPANISH'].value == 'es'
117+
assert graphene_type.__enum__.__members__['ENGLISH'].value == 'en'
118118

119119

120120
def test_should_float_convert_float():

graphene/contrib/sqlalchemy/converter.py

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ class ChoiceType(object):
1313
pass
1414

1515

16-
1716
def convert_sqlalchemy_relationship(relationship):
1817
direction = relationship.direction
1918
model = relationship.mapper.entity

graphene/core/classtypes/enum.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import six
22
from graphql.core.type import GraphQLEnumType, GraphQLEnumValue
33

4+
from .base import ClassTypeMeta, ClassType
5+
from ..types.base import MountedType
46
from ...utils.enum import Enum as PyEnum
5-
from .base import ClassType, ClassTypeMeta
67

78

89
class EnumMeta(ClassTypeMeta):
@@ -17,7 +18,12 @@ def construct(cls, bases, attrs):
1718
attrs[k] = v.value
1819
return super(EnumMeta, cls).construct(bases, attrs)
1920

20-
def __call__(cls, name, names=None, description=None):
21+
def __call__(cls, *args, **kwargs):
22+
if cls is Enum:
23+
return cls.create_enum(*args, **kwargs)
24+
return super(EnumMeta, cls).__call__(*args, **kwargs)
25+
26+
def create_enum(cls, name, names=None, description=None):
2127
attrs = {
2228
'__enum__': PyEnum(name, names)
2329
}
@@ -26,7 +32,7 @@ def __call__(cls, name, names=None, description=None):
2632
return type(name, (Enum,), attrs)
2733

2834

29-
class Enum(six.with_metaclass(EnumMeta, ClassType)):
35+
class Enum(six.with_metaclass(EnumMeta, ClassType, MountedType)):
3036

3137
class Meta:
3238
abstract = True

graphene/core/classtypes/tests/test_enum.py

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from graphene.core.schema import Schema
44

55
from ..enum import Enum
6+
from ..objecttype import ObjectType
67

78

89
def test_enum():
@@ -35,3 +36,14 @@ def test_enum_values():
3536
assert RGB.RED == 0
3637
assert RGB.GREEN == 1
3738
assert RGB.BLUE == 2
39+
40+
41+
def test_enum_instance():
42+
RGB = Enum('RGB', dict(RED=0, GREEN=1, BLUE=2))
43+
RGB_field = RGB(description='RGB enum description')
44+
45+
class ObjectWithColor(ObjectType):
46+
color = RGB_field
47+
48+
object_field = ObjectWithColor._meta.fields_map['color']
49+
assert object_field.description == 'RGB enum description'

graphene/utils/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .str_converters import to_camel_case, to_snake_case
1+
from .str_converters import to_camel_case, to_snake_case, to_const
22
from .proxy_snake_dict import ProxySnakeDict
33
from .caching import cached_property, memoize
44
from .maybe_func import maybe_func
@@ -7,6 +7,6 @@
77
from .lazylist import LazyList
88

99

10-
__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
10+
__all__ = ['to_camel_case', 'to_snake_case', 'to_const', 'ProxySnakeDict',
1111
'cached_property', 'memoize', 'maybe_func', 'enum_to_graphql_enum',
1212
'resolve_only_args', 'LazyList']

graphene/utils/str_converters.py

+4
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ def to_camel_case(snake_str):
1515
def to_snake_case(name):
1616
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
1717
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
18+
19+
20+
def to_const(string):
21+
return re.sub('[\W|^(?=\d)]+', '_', string).upper()

graphene/utils/tests/test_str_converter.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from ..str_converters import to_camel_case, to_snake_case
1+
# coding: utf-8
2+
from ..str_converters import to_camel_case, to_snake_case, to_const
23

34

45
def test_snake_case():
@@ -15,3 +16,7 @@ def test_camel_case():
1516
assert to_camel_case('snakes_on_a_plane') == 'snakesOnAPlane'
1617
assert to_camel_case('snakes_on_a__plane') == 'snakesOnA_Plane'
1718
assert to_camel_case('i_phone_hysteria') == 'iPhoneHysteria'
19+
20+
21+
def test_to_const():
22+
assert to_const('snakes $1. on a "#plane') == 'SNAKES_ON_A_PLANE'

0 commit comments

Comments
 (0)