-
Notifications
You must be signed in to change notification settings - Fork 819
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '1.0-django-interfaceobjecttype' into external-resolvers
- Loading branch information
Showing
99 changed files
with
2,970 additions
and
241 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +0,0 @@ | ||
|
||
from ..schema import Droid | ||
|
||
|
||
def test_query_types(): | ||
graphql_type = Droid._meta.graphql_type | ||
fields = graphql_type.get_fields() | ||
assert fields['friends'].parent == Droid | ||
assert fields | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import sys, os | ||
ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) | ||
sys.path.insert(0, ROOT_PATH + '/examples/') | ||
|
||
SECRET_KEY = 1 | ||
|
||
INSTALLED_APPS = [ | ||
'graphene_django', | ||
'graphene_django.tests', | ||
'starwars', | ||
] | ||
|
||
DATABASES = { | ||
'default': { | ||
'ENGINE': 'django.db.backends.sqlite3', | ||
'NAME': 'django_test.sqlite', | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from .types import ( | ||
DjangoObjectType, | ||
DjangoNode | ||
) | ||
from .fields import ( | ||
DjangoConnectionField, | ||
) | ||
|
||
__all__ = ['DjangoObjectType', 'DjangoNode', | ||
'DjangoConnectionField'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from django.db import models | ||
|
||
|
||
class MissingType(object): | ||
pass | ||
|
||
try: | ||
UUIDField = models.UUIDField | ||
except AttributeError: | ||
# Improved compatibility for Django 1.6 | ||
UUIDField = MissingType | ||
|
||
try: | ||
from django.db.models.related import RelatedObject | ||
except: | ||
# Improved compatibility for Django 1.6 | ||
RelatedObject = MissingType | ||
|
||
|
||
try: | ||
# Postgres fields are only available in Django 1.8+ | ||
from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField, RangeField | ||
except ImportError: | ||
ArrayField, HStoreField, JSONField, RangeField = (MissingType, ) * 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
from django.db import models | ||
from django.utils.encoding import force_text | ||
|
||
from graphene import Enum, List, ID, Boolean, Float, Int, String, Field | ||
from graphene.types.datetime import DateTime | ||
from graphene.utils.str_converters import to_const | ||
from graphene.relay import Node, ConnectionField | ||
# from ...core.types.custom_scalars import DateTime, JSONString | ||
from .compat import (ArrayField, HStoreField, JSONField, RangeField, | ||
RelatedObject, UUIDField) | ||
from .utils import get_related_model, import_single_dispatch | ||
from .fields import DjangoConnectionField | ||
|
||
singledispatch = import_single_dispatch() | ||
|
||
|
||
def convert_choices(choices): | ||
for value, name in choices: | ||
if isinstance(name, (tuple, list)): | ||
for choice in convert_choices(name): | ||
yield choice | ||
else: | ||
yield to_const(force_text(name)), value | ||
|
||
|
||
def convert_django_field_with_choices(field, registry=None): | ||
choices = getattr(field, 'choices', None) | ||
if choices: | ||
meta = field.model._meta | ||
name = '{}{}'.format(meta.object_name, field.name.capitalize()) | ||
graphql_choices = list(convert_choices(choices)) | ||
from collections import OrderedDict | ||
enum = Enum(name, OrderedDict(graphql_choices)) | ||
return enum(description=field.help_text) | ||
return convert_django_field(field, registry) | ||
|
||
|
||
@singledispatch | ||
def convert_django_field(field, registry=None): | ||
raise Exception( | ||
"Don't know how to convert the Django field %s (%s)" % | ||
(field, field.__class__)) | ||
|
||
|
||
@convert_django_field.register(models.CharField) | ||
@convert_django_field.register(models.TextField) | ||
@convert_django_field.register(models.EmailField) | ||
@convert_django_field.register(models.SlugField) | ||
@convert_django_field.register(models.URLField) | ||
@convert_django_field.register(models.GenericIPAddressField) | ||
@convert_django_field.register(models.FileField) | ||
@convert_django_field.register(UUIDField) | ||
def convert_field_to_string(field, registry=None): | ||
return String(description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(models.AutoField) | ||
def convert_field_to_id(field, registry=None): | ||
return ID(description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(models.PositiveIntegerField) | ||
@convert_django_field.register(models.PositiveSmallIntegerField) | ||
@convert_django_field.register(models.SmallIntegerField) | ||
@convert_django_field.register(models.BigIntegerField) | ||
@convert_django_field.register(models.IntegerField) | ||
def convert_field_to_int(field, registry=None): | ||
return Int(description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(models.BooleanField) | ||
def convert_field_to_boolean(field, registry=None): | ||
return Boolean(description=field.help_text, required=True) | ||
|
||
|
||
@convert_django_field.register(models.NullBooleanField) | ||
def convert_field_to_nullboolean(field, registry=None): | ||
return Boolean(description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(models.DecimalField) | ||
@convert_django_field.register(models.FloatField) | ||
def convert_field_to_float(field, registry=None): | ||
return Float(description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(models.DateField) | ||
def convert_date_to_string(field, registry=None): | ||
return DateTime(description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(models.OneToOneRel) | ||
def convert_onetoone_field_to_djangomodel(field, registry=None): | ||
model = get_related_model(field) | ||
return Field(registry.get_type_for_model(model)) | ||
|
||
|
||
@convert_django_field.register(models.ManyToManyField) | ||
@convert_django_field.register(models.ManyToManyRel) | ||
@convert_django_field.register(models.ManyToOneRel) | ||
def convert_field_to_list_or_connection(field, registry=None): | ||
model = get_related_model(field) | ||
_type = registry.get_type_for_model(model) | ||
if not _type: | ||
return | ||
|
||
if issubclass(_type, Node): | ||
return DjangoConnectionField(_type) | ||
return Field(List(_type)) | ||
|
||
|
||
# For Django 1.6 | ||
@convert_django_field.register(RelatedObject) | ||
def convert_relatedfield_to_djangomodel(field, registry=None): | ||
model = field.model | ||
_type = registry.get_type_for_model(model) | ||
if issubclass(_type, Node): | ||
return DjangoConnectionField(_type) | ||
return Field(List(_type)) | ||
|
||
|
||
@convert_django_field.register(models.OneToOneField) | ||
@convert_django_field.register(models.ForeignKey) | ||
def convert_field_to_djangomodel(field, registry=None): | ||
model = get_related_model(field) | ||
_type = registry.get_type_for_model(model) | ||
return Field(_type, description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(ArrayField) | ||
def convert_postgres_array_to_list(field, registry=None): | ||
base_type = convert_django_field(field.base_field) | ||
return List(base_type, description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(HStoreField) | ||
@convert_django_field.register(JSONField) | ||
def convert_posgres_field_to_string(field, registry=None): | ||
return JSONString(description=field.help_text) | ||
|
||
|
||
@convert_django_field.register(RangeField) | ||
def convert_posgres_range_to_string(field, registry=None): | ||
inner_type = convert_django_field(field.base_field) | ||
return List(inner_type, description=field.help_text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from .middleware import DjangoDebugMiddleware | ||
from .types import DjangoDebug | ||
|
||
__all__ = ['DjangoDebugMiddleware', 'DjangoDebug'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from promise import Promise | ||
from django.db import connections | ||
|
||
from .sql.tracking import unwrap_cursor, wrap_cursor | ||
from .types import DjangoDebug | ||
|
||
|
||
class DjangoDebugContext(object): | ||
|
||
def __init__(self): | ||
self.debug_promise = None | ||
self.promises = [] | ||
self.enable_instrumentation() | ||
self.object = DjangoDebug(sql=[]) | ||
|
||
def get_debug_promise(self): | ||
if not self.debug_promise: | ||
self.debug_promise = Promise.all(self.promises) | ||
return self.debug_promise.then(self.on_resolve_all_promises) | ||
|
||
def on_resolve_all_promises(self, values): | ||
self.disable_instrumentation() | ||
return self.object | ||
|
||
def add_promise(self, promise): | ||
if self.debug_promise and not self.debug_promise.is_fulfilled: | ||
self.promises.append(promise) | ||
|
||
def enable_instrumentation(self): | ||
# This is thread-safe because database connections are thread-local. | ||
for connection in connections.all(): | ||
wrap_cursor(connection, self) | ||
|
||
def disable_instrumentation(self): | ||
for connection in connections.all(): | ||
unwrap_cursor(connection) | ||
|
||
|
||
class DjangoDebugMiddleware(object): | ||
|
||
def resolve(self, next, root, args, context, info): | ||
django_debug = getattr(context, 'django_debug', None) | ||
if not django_debug: | ||
if context is None: | ||
raise Exception('DjangoDebug cannot be executed in None contexts') | ||
try: | ||
context.django_debug = DjangoDebugContext() | ||
except Exception: | ||
raise Exception('DjangoDebug need the context to be writable, context received: {}.'.format( | ||
context.__class__.__name__ | ||
)) | ||
if info.schema.graphene_schema.T(DjangoDebug) == info.return_type: | ||
return context.django_debug.get_debug_promise() | ||
promise = next(root, args, context, info) | ||
context.django_debug.add_promise(promise) | ||
return promise |
Empty file.
Oops, something went wrong.