Improved Django Connection resolver. Added exclude_fields option to Django Types

This commit is contained in:
Syrus Akbary 2015-10-03 01:47:55 -07:00
parent 52cb1715d3
commit dcd8edb59a
6 changed files with 53 additions and 5 deletions

View File

@ -2,3 +2,7 @@ from graphene.contrib.django.types import (
DjangoObjectType, DjangoObjectType,
DjangoNode DjangoNode
) )
from graphene.contrib.django.fields import (
DjangoConnectionField,
DjangoModelField
)

View File

@ -32,13 +32,13 @@ def lazy_map(value, func):
class DjangoConnectionField(relay.ConnectionField): class DjangoConnectionField(relay.ConnectionField):
def wrap_resolved(self, value, instance, args, info): def wrap_resolved(self, value, instance, args, info):
return lazy_map(value, instance.__class__) return lazy_map(value, self.field_type)
class LazyListField(ListField): class LazyListField(ListField):
def resolve(self, value, instance, args, info): def resolve(self, value, instance, args, info):
resolved = super(LazyListField, self).resolve(value, instance, args, info) resolved = super(LazyListField, self).resolve(value, instance, args, info)
return lazy_map(resolved, instance.__class__) return lazy_map(resolved, self.field_type)
class ConnectionOrListField(LazyField): class ConnectionOrListField(LazyField):

View File

@ -5,7 +5,7 @@ from graphene.core.options import Options
from graphene.core.types import BaseObjectType from graphene.core.types import BaseObjectType
from graphene.relay.utils import is_node from graphene.relay.utils import is_node
VALID_ATTRS = ('model', 'only_fields') VALID_ATTRS = ('model', 'only_fields', 'exclude_fields')
def is_base(cls): def is_base(cls):
@ -20,6 +20,7 @@ class DjangoOptions(Options):
super(DjangoOptions, self).__init__(*args, **kwargs) super(DjangoOptions, self).__init__(*args, **kwargs)
self.valid_attrs += VALID_ATTRS self.valid_attrs += VALID_ATTRS
self.only_fields = None self.only_fields = None
self.exclude_fields = []
def contribute_to_class(self, cls, name): def contribute_to_class(self, cls, name):
super(DjangoOptions, self).contribute_to_class(cls, name) super(DjangoOptions, self).contribute_to_class(cls, name)

View File

@ -27,7 +27,11 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
only_fields = cls._meta.only_fields only_fields = cls._meta.only_fields
reverse_fields = tuple(get_reverse_fields(cls._meta.model)) reverse_fields = tuple(get_reverse_fields(cls._meta.model))
for field in cls._meta.model._meta.fields + reverse_fields: for field in cls._meta.model._meta.fields + reverse_fields:
if only_fields and field.name not in only_fields: is_not_in_only = only_fields and field.name not in only_fields
is_excluded = field.name in cls._meta.exclude_fields
if is_not_in_only or is_excluded:
# We skip this field if we specify only_fields and is not
# in there. Or when we excldue this field in exclude_fields
continue continue
converted_field = convert_django_field(field, cls) converted_field = convert_django_field(field, cls)
cls.add_to_class(field.name, converted_field) cls.add_to_class(field.name, converted_field)

View File

@ -0,0 +1,40 @@
import json
from django.http import JsonResponse
from django.views.generic import View
from graphql.core.error import GraphQLError, format_error
def form_error(error):
if isinstance(error, GraphQLError):
return format_error(error)
return error
class GraphQLView(View):
schema = None
@staticmethod
def format_result(result):
data = {'data': result.data}
if result.errors:
data['errors'] = map(form_error, result.errors)
return data
def execute_query(self, request, query):
result = self.schema.execute(query, root=object())
data = self.format_result(result)
return JsonResponse(data)
def get(self, request, *args, **kwargs):
query = request.GET.get('query') or request.GET.get('q') or ''
return self.execute_query(request, query)
def post(self, request, *args, **kwargs):
if request.body:
received_json_data = json.loads(request.body)
query = received_json_data.get('query') or ''
else:
query = request.POST.get('query') or request.POST.get('q')
return self.execute_query(request, query)

View File

@ -2,7 +2,6 @@ from functools import wraps
class cached_property(object): class cached_property(object):
""" """
A property that is only computed once per instance and then replaces itself A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Deleting the attribute resets the property. with an ordinary attribute. Deleting the attribute resets the property.