Skip to main content

Expose Django models over GraphQL in the nestjs-query convention — the stock @refinedev/nestjs-query refine data provider drives Strawberry/Django, composing strawberry-django + strawberry-django-aggregates.

Project description

strawberry-django-nestjs

Expose Django models over GraphQL in the nestjs-query convention, so the stock @refinedev/nestjs-query refine data provider drives a Strawberry/Django backend with no patching.

It is a thin adapter: it composes strawberry-django (filters, ordering, pagination) and strawberry-django-aggregates (the compute_aggregation primitive) and emits the exact GraphQL shape the refine provider speaks. One unmodified frontend data provider, any Django model. The precise target SDL is in CONTRACT.md.

Why

refine's nestjs-query provider expects a specific GraphQL shape per resource: a notes(filter, sorting, paging): NoteConnection list, a note(id): Note detail, createOneNote / updateOneNote / deleteOneNote mutations, NoteFilter operator objects, NoteSort + SortDirection, OffsetPaging, and a noteAggregate group-by surface. This library emits all of it from your Strawberry types — you keep the stock provider, no custom mapping layer.

Install

pip install strawberry-django-nestjs
# or
uv add strawberry-django-nestjs

Requires Python 3.14+, Django 6.0+, and a Strawberry/strawberry-django stack (installed transitively).

Quickstart

Declare the per-model nestjs types from your Strawberry types, then compose the adapter's helpers in plain resolvers. (Condensed from examples/demo_schema.py, which exercises every surface.)

import enum
import strawberry
import strawberry_django
from strawberry import UNSET, auto

from strawberry_django_nestjs import (
    AggregateField, Connection, OffsetPaging, SortDirection, SortNulls,
    apply_sorting, build_aggregate_types, filter_to_q, input_to_dict,
    make_aggregate_resolver, paginate,
)
from strawberry_django_nestjs.comparisons import (
    NumberFieldComparison, StringFieldComparison,
)

from .models import Note  # your Django model


@strawberry_django.type(Note)
class NoteType:           # GraphQL type name `Note`
    id: auto
    title: auto
    word_count: auto
    status: auto


@strawberry.input
class NoteFilter:
    title: StringFieldComparison | None = UNSET
    status: StringFieldComparison | None = UNSET
    word_count: NumberFieldComparison | None = UNSET
    and_: list["NoteFilter"] | None = strawberry.field(name="and", default=UNSET)
    or_: list["NoteFilter"] | None = strawberry.field(name="or", default=UNSET)


@strawberry.enum
class NoteSortFields(enum.Enum):   # field value = the Django column name
    title = "title"
    word_count = "word_count"


@strawberry.input
class NoteSort:
    field: NoteSortFields
    direction: SortDirection
    nulls: SortNulls | None = UNSET


def base_qs():
    # Apply your row-level (e.g. REBAC) scoping here — reads run on this.
    return Note.objects.all()


# Declare the aggregate surface once; the same list builds the
# `<Model>Aggregate` types and maps GraphQL (camelCase) names to columns.
AGG_FIELDS = [
    AggregateField("title", str),
    AggregateField("word_count", int, numeric=True),
    AggregateField("status", str),
]
NoteAggregateResponse, _blocks = build_aggregate_types("Note", AGG_FIELDS)
note_aggregate = make_aggregate_resolver(
    NoteAggregateResponse, _blocks, AGG_FIELDS,
    base_queryset=base_qs, filter_to_q=filter_to_q,
)


@strawberry.type
class Query:
    @strawberry.field
    def notes(
        self,
        filter: NoteFilter | None = None,
        sorting: list[NoteSort] | None = None,
        paging: OffsetPaging | None = None,
    ) -> Connection[NoteType]:
        qs = apply_sorting(base_qs().filter(filter_to_q(filter)), sorting)
        return Connection(nodes=list(paginate(qs, paging)), total_count=qs.count())

    @strawberry.field
    def note(self, id: strawberry.ID) -> NoteType | None:
        return base_qs().filter(pk=id).first()

    @strawberry.field
    def note_aggregate(
        self, info: strawberry.Info, filter: NoteFilter | None = None
    ) -> list[NoteAggregateResponse]:
        return note_aggregate(info, filter=filter)

createOne / updateOne / deleteOne mutations follow the same pattern, using input_to_dict to translate the nestjs input envelope into model kwargs. Your <Model>Update input type is the authoritative writable-field allowlist (keep server-owned columns out of it); run the updateOne read-modify-write inside transaction.atomic() and save(update_fields=…) so a patch touches only the columns it set (plus any auto_now columns you want refreshed, which update_fields otherwise skips) — see examples/demo_schema.py.

The five surfaces

Surface Module What it emits / does
Filtering comparisons, filtering <Model>Filter operator objects → a Django Q
Sorting sorting, types [<Model>Sort!] + SortDirection/SortNulls.order_by()
Pagination connection OffsetPaging + <Model>Connection { nodes, totalCount }
Mutations mutations createOne/updateOne/deleteOne input envelope → model kwargs
Aggregation aggregation selection-driven <Model>Aggregate group-by, composing compute_aggregation

Proof: the stock provider drives it

examples/ is a runnable proof that the unmodified @refinedev/nestjs-query provider drives a schema built with this library (getList / getOne / create / update / deleteOne), no patching.

Status

Beta (v0.1.0). The public API (__init__ exports) and the emitted SDL shape follow CONTRACT.md and are stable for early adopters; minor iteration is expected before a 1.0 stability commitment. Runtime: Python 3.14, Django 6.0.

Documentation

License

AGPL-3.0-or-later. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

strawberry_django_nestjs-0.1.0.tar.gz (29.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

strawberry_django_nestjs-0.1.0-py3-none-any.whl (26.0 kB view details)

Uploaded Python 3

File details

Details for the file strawberry_django_nestjs-0.1.0.tar.gz.

File metadata

  • Download URL: strawberry_django_nestjs-0.1.0.tar.gz
  • Upload date:
  • Size: 29.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for strawberry_django_nestjs-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1de2abb779f422d97d918a32f41253624c57da781ed5a3e3a29000f140a7bd30
MD5 4ab152523c36f188053d6ac9d8d7c1a6
BLAKE2b-256 2068c5a070af2af9b02901c9a95afa8a00ce0c443722b7a69107637051b34a86

See more details on using hashes here.

File details

Details for the file strawberry_django_nestjs-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for strawberry_django_nestjs-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 beb1e11247e68704c91b5ff3047da96545a4c6e1a6e2c79b13111b80a8b217a9
MD5 9aad8da762538cf503e20c750073d7ce
BLAKE2b-256 2894b1364801f67a54fa677ff7f0ee56e973231264fe39699ecbfbe14962933a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page