Changelog¶
All notable changes to this library are documented here. The format is based on Keep a Changelog and the project adheres to Semantic Versioning.
A fresh start
django-graphex is a new, rewritten library — the successor to
graphene-django-extras. Its history starts at 1.0.0 below. If you are
coming from graphene-django-extras 1.x, the Migration Guide
explains every change with before/after examples (install django-graphex,
import django_graphex).
1.0.0¶
The first release. A GraphQL + Django toolkit built directly on graphene
(graphene-core) and Pydantic v2 — no graphene-django, no
djangorestframework, no django-filter.
Model types, mutations & the native backend¶
DjangoModelType/DjangoModelMutation— define a Django model once and get query, list and create/update/delete operations. Backed byMeta.modeland a native Pydantic v2SerializerBackendthat validates and persists with the Django ORM (field types,max_length,Decimalprecision, required/nullable/ defaults,choices→Enum, FK pk types, M2M as a list of pks), and runs the DB-level checks Pydantic can't — FK existence, uniqueness andunique_together. Supports partial updates.- Custom validation without a serializer: declare DRF-style inline
validate_<field>(self, value)and an object-levelvalidate(self, data)directly on the class, and/or pass aMeta.pydantic_modelwith validators (they compose). - Atomic, relation-aware nested writes —
Meta.nested_fields = {field: Model}for forward FK, reverse FK and M2M children, written in one transaction (parent or child failure rolls everything back) withfield.subfielderror paths. - Custom output fields declared on a
DjangoModelTypeare honored, including theirresolve_<field>resolver methods (andsource=), inherited/overridable down the MRO.
Filtering¶
- Native
and/or/notfiltering through a single nestedfilter:argument (a generated<Model>FilterInput), built on Django's ORM lookups +Qobjects. Per-field lookups, relation descent (auto.distinct()on to-many joins), plain-pk /UUIDFieldfiltering (id: { exact/in }), andchoicesfiltered via theirEnum. Declared withMeta.filter_fields(list or dict form); the common base lookup set is configurable viaCOMMON_FILTER_LOOKUPS. AFilterBackendseam keeps it swappable. - Custom filtering logic via the
get_queryset/filter_querysethooks.
Lists, pagination & performance¶
- Three paginators —
LimitOffsetGraphqlPagination,PageGraphqlPaginationandCursorGraphqlPagination(keyset cursor with a non-opaquepageInfo). Pagination/ordering live on theresults(...)subfield; lists expose the uniformresults/totalCountshape, including nested related lists. - Automatic N+1 query optimization —
select_related/prefetch_related/.only()derived from the GraphQL selection (incl. filtered nested-list prefetches), tunable withOPTIMIZE_QUERYSET/OPTIMIZE_ONLY_FIELDS. - An effective
MAX_PAGE_SIZEceiling applied even when no page-size arg is sent.
Subscriptions¶
- Real-time GraphQL subscriptions over Django Channels 4 (optional
[subscriptions]extra) with an in-house signal →group_sendengine; configurable notification payload (id-only vs full) and value-scoped "indexed" groups.
Permissions & security¶
- DRF-style permission classes (
BasePermission,IsAuthenticated,IsAdmin,IsAuthenticatedOrReadOnly, …) usable on types, subscriptions and views. - Query depth limiting (
MAX_QUERY_DEPTH/Meta.max_deep) and query cost analysis (MAX_QUERY_COST/Meta.complexity, optionalextensions.cost). - Security middlewares —
DisableIntrospectionMiddleware,AuthenticatedFieldsMiddleware— andExtraGraphQLSchemafor declaring private fields. Every execution error carries a machine-readableextensions.code.
Views¶
GraphQLView(response caching + depth/cost rules +extensions.cost),BaseGraphQLView(minimal, self-contained — nographene-django), andAuthenticatedGraphQLView(endpoint-level auth gate via the library's own permission classes, no DRF). GraphiQL is served from a self-contained CDN page, overridable withgraphiql_templatefor offline / strict-CSP setups.
Directives¶
- Schema directives for string/number/list/date transforms (
@title_case,@snake_case,@slugify,@truncate,@round,@abs,@unique,@date, …; custom directive names are snake_case), with directive arguments as GraphQL variables.
Requirements¶
- Python 3.12–3.14, Django 4.0–6.0, graphene >=3.3,<4, pydantic >=2,<3.