Port GraphQLView to Graphene 3

This commit is contained in:
Tomasz Kontusz 2019-09-15 22:07:41 +02:00
parent 8412fee863
commit 5bd4d31c89
2 changed files with 24 additions and 39 deletions

View File

@ -9,7 +9,6 @@ from .types import DictType
singledispatch = import_single_dispatch() singledispatch = import_single_dispatch()
@singledispatch @singledispatch
def get_graphene_type_from_serializer_field(field): def get_graphene_type_from_serializer_field(field):
raise ImproperlyConfigured( raise ImproperlyConfigured(

View File

@ -9,8 +9,9 @@ from django.shortcuts import render
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.generic import View from django.views.generic import View
from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.csrf import ensure_csrf_cookie
from graphene import Schema
from graphql import parse, get_operation_ast, OperationType, execute, validate
from graphql import get_default_backend
from graphql.error import format_error as format_graphql_error from graphql.error import format_error as format_graphql_error
from graphql.error import GraphQLError from graphql.error import GraphQLError
from graphql.execution import ExecutionResult from graphql.execution import ExecutionResult
@ -55,10 +56,8 @@ class GraphQLView(View):
graphiql_template = "graphene/graphiql.html" graphiql_template = "graphene/graphiql.html"
react_version = "16.8.6" react_version = "16.8.6"
schema = None schema: Schema = None
graphiql = False graphiql = False
executor = None
backend = None
middleware = None middleware = None
root_value = None root_value = None
pretty = False pretty = False
@ -67,35 +66,28 @@ class GraphQLView(View):
def __init__( def __init__(
self, self,
schema=None, schema=None,
executor=None,
middleware=None, middleware=None,
root_value=None, root_value=None,
graphiql=False, graphiql=False,
pretty=False, pretty=False,
batch=False, batch=False,
backend=None,
): ):
if not schema: if not schema:
schema = graphene_settings.SCHEMA schema = graphene_settings.SCHEMA
if backend is None:
backend = get_default_backend()
if middleware is None: if middleware is None:
middleware = graphene_settings.MIDDLEWARE middleware = graphene_settings.MIDDLEWARE
self.schema = self.schema or schema self.schema = self.schema or schema
if middleware is not None: if middleware is not None:
self.middleware = list(instantiate_middleware(middleware)) self.middleware = list(instantiate_middleware(middleware))
self.executor = executor
self.root_value = root_value self.root_value = root_value
self.pretty = self.pretty or pretty self.pretty = self.pretty or pretty
self.graphiql = self.graphiql or graphiql self.graphiql = self.graphiql or graphiql
self.batch = self.batch or batch self.batch = self.batch or batch
self.backend = backend
assert isinstance( assert isinstance(
self.schema, GraphQLSchema self.schema, Schema
), "A Schema is required to be provided to GraphQLView." ), "A Schema is required to be provided to GraphQLView."
assert not all((graphiql, batch)), "Use either graphiql or batch processing" assert not all((graphiql, batch)), "Use either graphiql or batch processing"
@ -109,9 +101,6 @@ class GraphQLView(View):
def get_context(self, request): def get_context(self, request):
return request return request
def get_backend(self, request):
return self.backend
@method_decorator(ensure_csrf_cookie) @method_decorator(ensure_csrf_cookie)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
try: try:
@ -173,7 +162,9 @@ class GraphQLView(View):
self.format_error(e) for e in execution_result.errors self.format_error(e) for e in execution_result.errors
] ]
if execution_result.invalid: if execution_result.errors and any(
not e.path for e in execution_result.errors
):
status_code = 400 status_code = 400
else: else:
response["data"] = execution_result.data response["data"] = execution_result.data
@ -246,14 +237,13 @@ class GraphQLView(View):
raise HttpError(HttpResponseBadRequest("Must provide query string.")) raise HttpError(HttpResponseBadRequest("Must provide query string."))
try: try:
backend = self.get_backend(request) document = parse(query)
document = backend.document_from_string(self.schema, query)
except Exception as e: except Exception as e:
return ExecutionResult(errors=[e], invalid=True) return ExecutionResult(errors=[e])
if request.method.lower() == "get": if request.method.lower() == "get":
operation_type = document.get_operation_type(operation_name) operation_ast = get_operation_ast(document, operation_name)
if operation_type and operation_type != "query": if operation_ast and operation_ast.operation != OperationType.QUERY:
if show_graphiql: if show_graphiql:
return None return None
@ -261,28 +251,24 @@ class GraphQLView(View):
HttpResponseNotAllowed( HttpResponseNotAllowed(
["POST"], ["POST"],
"Can only perform a {} operation from a POST request.".format( "Can only perform a {} operation from a POST request.".format(
operation_type operation_ast.operation.value
), ),
) )
) )
try: validation_errors = validate(self.schema.graphql_schema, document)
extra_options = {} if validation_errors:
if self.executor: return ExecutionResult(data=None, errors=validation_errors)
# We only include it optionally since
# executor is not a valid argument in all backends
extra_options["executor"] = self.executor
return document.execute( return execute(
root=self.get_root_value(request), schema=self.schema.graphql_schema,
variables=variables, document=document,
root_value=self.get_root_value(request),
variable_values=variables,
operation_name=operation_name, operation_name=operation_name,
context=self.get_context(request), context_value=self.get_context(request),
middleware=self.get_middleware(request), middleware=self.get_middleware(request),
**extra_options
) )
except Exception as e:
return ExecutionResult(errors=[e], invalid=True)
@classmethod @classmethod
def can_display_graphiql(cls, request, data): def can_display_graphiql(cls, request, data):