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,
DjangoNode
)
from graphene.contrib.django.fields import (
DjangoConnectionField,
DjangoModelField
)

View File

@ -32,13 +32,13 @@ def lazy_map(value, func):
class DjangoConnectionField(relay.ConnectionField):
def wrap_resolved(self, value, instance, args, info):
return lazy_map(value, instance.__class__)
return lazy_map(value, self.field_type)
class LazyListField(ListField):
def resolve(self, 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):

View File

@ -5,7 +5,7 @@ from graphene.core.options import Options
from graphene.core.types import BaseObjectType
from graphene.relay.utils import is_node
VALID_ATTRS = ('model', 'only_fields')
VALID_ATTRS = ('model', 'only_fields', 'exclude_fields')
def is_base(cls):
@ -20,6 +20,7 @@ class DjangoOptions(Options):
super(DjangoOptions, self).__init__(*args, **kwargs)
self.valid_attrs += VALID_ATTRS
self.only_fields = None
self.exclude_fields = []
def contribute_to_class(self, 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
reverse_fields = tuple(get_reverse_fields(cls._meta.model))
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
converted_field = convert_django_field(field, cls)
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):
"""
A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Deleting the attribute resets the property.