Registry /
database / graphene-django-optimizer
Install & Compatibility
Where this runs
tested against v0.10.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 17.9MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 1.5s · import 0.000s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
DjangoOptimizerExtension
✓ from graphene_django_optimizer import DjangoOptimizerExtension
✗ from graphene_django_optimizer import DjangoOptimizerExtension
This quickstart demonstrates how to integrate `graphene-django-optimizer` by adding `DjangoOptimizerExtension` to your `GRAPHENE['EXTENSIONS']` settings. This global setting ensures that all `DjangoObjectType` fields are automatically optimized, preventing N+1 queries for `select_related` and `prefetch_related` relationships specified in your GraphQL query. The example sets up a minimal Django environment and Graphene schema to illustrate usage.
import graphene
from django.db import models
from django.conf import settings
from graphene_django.types import DjangoObjectType
from graphene_django_optimizer import DjangoOptimizerExtension
# Minimal Django setup required for DjangoObjectType to function
# In a real Django project, these settings would be in your settings.py
if not settings.configured:
settings.configure(
INSTALLED_APPS=['graphene_django', 'graphene_django_optimizer', 'myapp'],
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
GRAPHENE={'EXTENSIONS': [DjangoOptimizerExtension]}, # Enable globally via settings
# Needed for Django models to be discovered
MIGRATION_MODULES={'myapp': None}
)
import django
django.setup()
# Define a simple Django model
class Author(models.Model):
name = models.CharField(max_length=100)
class Meta:
app_label = 'myapp' # Critical for in-memory Django setup
class Book(models.Model):
title = models.CharField(max_length=200)
author_obj = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
class Meta:
app_label = 'myapp'
# Define Graphene types for the models
class AuthorType(DjangoObjectType):
class Meta:
model = Author
fields = ("id", "name", "books")
class BookType(DjangoObjectType):
class Meta:
model = Book
fields = ("id", "title", "author_obj")
# Define a Graphene Query
class Query(graphene.ObjectType):
all_authors = graphene.List(AuthorType)
all_books = graphene.List(BookType)
def resolve_all_authors(root, info):
# The DjangoOptimizerExtension will automatically apply select_related/prefetch_related
# for related fields requested in the GraphQL query (e.g., 'books' on AuthorType)
return Author.objects.all()
def resolve_all_books(root, info):
return Book.objects.all()
# Create the Graphene Schema
# The extension is enabled via settings.GRAPHENE['EXTENSIONS']
schema = graphene.Schema(query=Query)
# --- Example Usage (for demonstration, not typically part of quickstart.code) ---
# Create some dummy data
author1 = Author.objects.create(name="Douglas Adams")
author2 = Author.objects.create(name="Jane Austen")
Book.objects.create(title="The Hitchhiker's Guide to the Galaxy", author_obj=author1)
Book.objects.create(title="Pride and Prejudice", author_obj=author2)
Book.objects.create(title="The Restaurant at the End of the Universe", author_obj=author1)
# Define a GraphQL query that would typically cause N+1 without optimization
query = """
query {
allBooks {
id
title
author_obj {
name
}
}
}
"""
# Execute the query
result = schema.execute(query)
# Check for errors and data (in a real scenario, you'd inspect logs for N+1)
assert not result.errors
assert len(result.data['allBooks']) == 3
assert result.data['allBooks'][0]['author_obj']['name'] == 'Douglas Adams'
print("Optimization enabled successfully! Check your database query logs if available.")
Debug
Known issues
breakingVersion 0.9.0 introduced support for Graphene 3, simultaneously dropping support for Graphene 2. If you are using Graphene 2, you must pin your `graphene-django-optimizer` version to `<0.9.0` (e.g., use `~=0.8.0`).fixFor Graphene 3 projects, upgrade `graphene-django-optimizer` to `^0.9.0`. For Graphene 2 projects, downgrade `graphene-django-optimizer` to `~=0.8.0`.
affects: >=0.9.0
gotchaVersion 0.10.0 fixed a compatibility issue with `graphql-core v3.2`. If you are using `graphql-core >= 3.2` with `graphene-django-optimizer < 0.10.0`, you might encounter runtime errors or unexpected behavior.fixEnsure you are using `graphene-django-optimizer >= 0.10.0` when your project includes `graphql-core >= 3.2`.
affects: <0.10.0 with graphql-core >=3.2
breakingVersions prior to 0.6.0 supported older Django and Python versions. Current versions (>=0.6.0) require Django `>=2.2` and Python `>=3.6`.fixUpgrade your Django installation to `2.2` or newer and Python to `3.6` or newer, or pin `graphene-django-optimizer` to an older compatible version if using legacy environments.
affects: <0.6.0
gotchaAutomatic optimization through `DjangoOptimizerExtension` only applies to fields resolved by `DjangoObjectType`'s default resolver. For custom resolvers, you must manually apply `QueryOptimizer.optimize_query(queryset, info)` or use the `@optimize` decorator.fixReview custom resolvers to ensure they explicitly call `QueryOptimizer.optimize_query(queryset, info)` or are decorated with `@optimize` to prevent N+1 queries.
affects: *
Upgrade
Version history
0.10.0latest on PyPI · released Aug 5, 2023
Audit
Dependencies
DjangorequiredCore ORM and web framework. Requires >=2.2,<5.0.
graphene-djangorequiredConnects Graphene with Django models. Requires >=2.15,<4.0.
graphenerequiredCore GraphQL library. Requires >=2.1,<4.0.
graphql-corerequiredLow-level GraphQL implementation. Requires >=2.1,<4.0.