Django integration for Graphene enabling GraphQL APIs in Django applications
—
Django view classes for serving GraphQL endpoints with configurable GraphiQL interface, middleware support, and comprehensive HTTP request handling. These views provide the bridge between Django's HTTP layer and GraphQL execution.
Django view for serving GraphQL endpoints with built-in GraphiQL support, middleware integration, and flexible configuration options.
class GraphQLView(django.views.generic.View):
"""
Django view for serving GraphQL endpoint with GraphiQL support.
Handles GET requests for GraphiQL interface and POST requests for
GraphQL query execution with comprehensive error handling and
middleware integration.
"""
schema = None # GraphQL schema
executor = None # Custom executor
middleware = None # GraphQL middleware
graphiql = False # Enable GraphiQL interface
pretty = False # Pretty print JSON responses
batch = False # Enable query batching
def __init__(self, schema=None, executor=None, middleware=None,
graphiql=False, pretty=False, batch=False, **kwargs):
"""
Initialize GraphQL view.
Parameters:
- schema: GraphQL schema instance
- executor: Custom GraphQL executor
- middleware: List of GraphQL middleware
- graphiql: Enable GraphiQL development interface
- pretty: Pretty print JSON responses
- batch: Enable batched query execution
- **kwargs: Additional view options
"""
def dispatch(self, request, *args, **kwargs):
"""
Handle HTTP requests and route to appropriate methods.
Parameters:
- request: Django HTTP request
- *args: URL arguments
- **kwargs: URL keyword arguments
Returns:
django.http.HttpResponse: HTTP response
"""
def get_response(self, request, data, show_graphiql=False):
"""
Process GraphQL requests and return responses.
Parameters:
- request: Django HTTP request
- data: GraphQL query data
- show_graphiql: Whether to show GraphiQL interface
Returns:
django.http.HttpResponse: GraphQL response
"""
def render_graphiql(self, request, **data):
"""
Render GraphiQL development interface.
Parameters:
- request: Django HTTP request
- **data: GraphiQL configuration data
Returns:
django.http.HttpResponse: GraphiQL HTML response
"""
def get_graphql_params(self, request, data):
"""
Extract GraphQL parameters from request.
Parameters:
- request: Django HTTP request
- data: Request data
Returns:
dict: GraphQL execution parameters (query, variables, operation_name)
"""
def format_error(self, error):
"""
Format GraphQL execution errors.
Parameters:
- error: GraphQL execution error
Returns:
dict: Formatted error data
"""
def get_context(self, request):
"""
Get GraphQL execution context from request.
Parameters:
- request: Django HTTP request
Returns:
dict: Execution context
"""
def can_display_graphiql(self, request, data):
"""
Determine if GraphiQL interface should be displayed.
Parameters:
- request: Django HTTP request
- data: Request data
Returns:
bool: True if GraphiQL should be shown
"""
@classmethod
def as_view(cls, **initkwargs):
"""
Create view instance with configuration.
Parameters:
- **initkwargs: View initialization arguments
Returns:
function: Configured view function
"""HTTP-specific exception for GraphQL errors with response status code control and custom error messaging.
class HttpError(Exception):
"""
HTTP-specific exception for GraphQL errors.
Allows GraphQL resolvers to return specific HTTP status codes
and custom error responses for client error handling.
"""
def __init__(self, response, message=None, *args, **kwargs):
"""
Initialize HTTP error.
Parameters:
- response: django.http.HttpResponse or status code
- message: Error message
- *args: Additional exception arguments
- **kwargs: Additional exception keyword arguments
"""
self.response = response
self.message = message
super().__init__(message, *args, **kwargs)from django.urls import path
from graphene_django.views import GraphQLView
from myapp.schema import schema
urlpatterns = [
path('graphql/', GraphQLView.as_view(schema=schema)),
]from django.conf import settings
urlpatterns = [
path('graphql/', GraphQLView.as_view(
schema=schema,
graphiql=settings.DEBUG # Enable GraphiQL in development
)),
]from graphene_django.debug import DjangoDebugMiddleware
class CustomGraphQLView(GraphQLView):
def get_context(self, request):
return {
'request': request,
'user': request.user,
}
urlpatterns = [
path('graphql/', CustomGraphQLView.as_view(
schema=schema,
middleware=[DjangoDebugMiddleware()],
graphiql=True
)),
]from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@method_decorator(login_required, name='dispatch')
class ProtectedGraphQLView(GraphQLView):
pass
urlpatterns = [
path('api/graphql/', ProtectedGraphQLView.as_view(schema=schema)),
]import json
from django.http import JsonResponse
class CustomGraphQLView(GraphQLView):
def format_error(self, error):
formatted_error = super().format_error(error)
# Add custom error logging
if hasattr(error, 'original_error'):
logger.error(f"GraphQL Error: {error.original_error}")
return formatted_error
def get_response(self, request, data, show_graphiql=False):
try:
return super().get_response(request, data, show_graphiql)
except Exception as e:
return JsonResponse({
'errors': [{'message': 'Internal server error'}]
}, status=500)urlpatterns = [
path('graphql/', GraphQLView.as_view(
schema=schema,
batch=True, # Enable query batching
graphiql=True
)),
]
# Client can send multiple queries:
# POST /graphql/
# [
# {"query": "query { users { id } }"},
# {"query": "query { posts { title } }"}
# ]from graphql import GraphQLError
from concurrent.futures import ThreadPoolExecutor
def custom_executor(fn, *args, **kwargs):
"""Custom executor with thread pool."""
with ThreadPoolExecutor(max_workers=4) as executor:
return executor.submit(fn, *args, **kwargs).result()
urlpatterns = [
path('graphql/', GraphQLView.as_view(
schema=schema,
executor=custom_executor
)),
]from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class CORSGraphQLView(GraphQLView):
def dispatch(self, request, *args, **kwargs):
response = super().dispatch(request, *args, **kwargs)
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
return responsefrom graphene_django.views import HttpError
from django.http import HttpResponseForbidden
class Query(graphene.ObjectType):
sensitive_data = graphene.String()
def resolve_sensitive_data(self, info):
if not info.context.user.is_staff:
raise HttpError(
HttpResponseForbidden("Access denied"),
message="Insufficient permissions"
)
return "Secret information"Install with Tessl CLI
npx tessl i tessl/pypi-graphene-django