Port GraphQLView to Graphene 3

This commit is contained in:
Tomasz Kontusz 2019-09-15 22:07:41 +02:00 committed by Jean-Louis Fuchs
parent 5a662c9d03
commit 10269267a4
No known key found for this signature in database
GPG Key ID: 3440F981335FD30F

View File

@ -6,15 +6,16 @@ from django.http import HttpResponse, HttpResponseNotAllowed
from django.http.response import HttpResponseBadRequest from django.http.response import HttpResponseBadRequest
from django.shortcuts import render 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.decorators.csrf import ensure_csrf_cookie from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic import View
from graphql import get_default_backend from graphql import OperationType, execute, get_operation_ast, parse, validate
from graphql.error import format_error as format_graphql_error
from graphql.error import GraphQLError from graphql.error import GraphQLError
from graphql.error import format_error as format_graphql_error
from graphql.execution import ExecutionResult from graphql.execution import ExecutionResult
from graphql.type.schema import GraphQLSchema from graphql.type.schema import GraphQLSchema
from graphene import Schema
from .settings import graphene_settings from .settings import graphene_settings
@ -56,8 +57,6 @@ class GraphQLView(View):
schema = None schema = None
graphiql = False graphiql = False
executor = None
backend = None
middleware = None middleware = None
root_value = None root_value = None
pretty = False pretty = False
@ -66,35 +65,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"
@ -108,9 +100,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:
@ -172,7 +161,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
@ -245,14 +236,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
@ -260,28 +250,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(
schema=self.schema.graphql_schema,
document=document,
root_value=self.get_root_value(request), root_value=self.get_root_value(request),
variable_values=variables, variable_values=variables,
operation_name=operation_name, operation_name=operation_name,
context_value=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):