Metadata-Version: 2.5
Name: django-fastdrf
Version: 0.1.0
Summary: Opt-in serializer and query optimizations for synchronous Django REST framework.
Project-URL: Homepage, https://github.com/ctolon/django-fastdrf
Project-URL: Documentation, https://github.com/ctolon/django-fastdrf/tree/main/docs
Project-URL: Changelog, https://github.com/ctolon/django-fastdrf/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/ctolon/django-fastdrf/issues
Project-URL: Source, https://github.com/ctolon/django-fastdrf
Author: Cevat Batuhan Tolon
License-Expression: BSD-3-Clause
License-File: LICENSE
License-File: NOTICE
Keywords: django,django-rest-framework,msgspec,performance,serializers
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: Django :: 6.0
Classifier: Framework :: Django :: 6.1
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: django>=5.2
Requires-Dist: djangorestframework>=3.16
Provides-Extra: msgspec
Requires-Dist: msgspec>=0.19; extra == 'msgspec'
Provides-Extra: pydantic
Requires-Dist: pydantic>=2.9; extra == 'pydantic'
Description-Content-Type: text/markdown

# django-fastdrf

Opt-in serializer, query and response optimizations for synchronous
[Django REST framework](https://www.django-rest-framework.org/) projects.

django-fastdrf is for DRF projects that stay synchronous (WSGI, or ASGI with
synchronous views) and want less time per request without leaving DRF. It
adds subclasses, mixins and settings next to DRF's own classes. Each
optimization is enabled explicitly, per project, per view or per serializer,
and falls back to DRF's code wherever it cannot produce DRF's result.

It does not replace or patch any Django or DRF class, add async support, or
change DRF's validation errors.

## Installation

```console
pip install django-fastdrf
```

The distribution is `django-fastdrf`; the import name is `fastdrf`. Two
extras install the optional backends:

```console
pip install "django-fastdrf[msgspec]"    # msgspec backend, renderer, parser, codec
pip install "django-fastdrf[pydantic]"   # pydantic backend, schema serializers, codec
```

Adding `"fastdrf"` to `INSTALLED_APPS` is optional. It registers system checks
and two management commands; everything else works without it.

## Quick start

Use fastdrf's serializer bases and choose a backend for their output:

```python
# settings.py
FASTDRF = {
    "SERIALIZER_BACKEND": "msgspec",  # or "pydantic", or "python" (no dependency)
    "CACHE_SERIALIZER_FIELDS": True,
    "FIELD_COPY_MODE": "compiled",
}
```

```python
# serializers.py
from fastdrf import serializers


class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ["id", "title", "author", "published_at"]
        auto_prefetch = True
```

```python
# views.py
from rest_framework import viewsets

from fastdrf.views import DispatchOptimizationMixin, QueryOptimizationMixin


class ArticleViewSet(
    DispatchOptimizationMixin, QueryOptimizationMixin, viewsets.ModelViewSet
):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
```

`.data`, `.is_valid()`, `.save()`, `many=True`, routers, pagination,
permissions and error responses are DRF's. With `"fastdrf"` in
`INSTALLED_APPS`, this command lists which serializers the backend compiles,
and why the others stay on DRF:

```console
python manage.py fastdrf_inspect_serializers
```

## Features

Serialization:

- Compiled serializer output with the msgspec, pydantic or dependency-free
  `python` backend, equal to DRF's `.data` in the default strict parity mode
  ([serializers](https://github.com/ctolon/django-fastdrf/blob/main/docs/serializers.md#output-backends)).
- Input recognition: JSON input that DRF would accept unchanged is validated
  by a compiled class; everything else, including every error, is DRF's
  ([input recognition](https://github.com/ctolon/django-fastdrf/blob/main/docs/serializers.md#input-recognition)).
- Cached field templates, copied per request with `deepcopy`, a scalar clone
  or a compiled copy plan
  ([field caching](https://github.com/ctolon/django-fastdrf/blob/main/docs/serializers.md#field-caching-and-copying)).
- List serializers whose child refers to the list weakly
  ([list serializers](https://github.com/ctolon/django-fastdrf/blob/main/docs/serializers.md#list-serializers)).
- Schema serializers: a msgspec `Struct` or a pydantic model as a DRF
  serializer, and `SchemaViewMixin` for views
  ([schema serializers](https://github.com/ctolon/django-fastdrf/blob/main/docs/schema-serializers.md)).

Queries:

- `select_related` and `prefetch_related` derived from the serializer by
  `QueryOptimizationMixin`, explicit `Meta.prefetch` hints, Django 6.1's
  `FETCH_MODE`, one query for many-valued primary-key input, and
  `PrefetchListSerializer` for per-list enrichment
  ([queries](https://github.com/ctolon/django-fastdrf/blob/main/docs/queries.md)).

Views and responses:

- Dispatch mixins that keep content negotiation and request construction
  between requests, compiled create and update responses, a `Response` that
  releases its request objects when closed, and `DataResponse`, rendered
  without DRF's template response
  ([views and responses](https://github.com/ctolon/django-fastdrf/blob/main/docs/views.md)).
- A `JSONRenderer` that keeps its encoder, msgspec's JSON renderer and
  parser, and msgspec and pydantic codecs for Django's Redis cache
  ([rendering and codecs](https://github.com/ctolon/django-fastdrf/blob/main/docs/rendering.md)).

Tooling:

- System checks for the `FASTDRF` setting and two management commands:
  `fastdrf_inspect_serializers` and `fastdrf_convert`, which writes a schema
  for a serializer or a serializer for a schema
  ([commands](https://github.com/ctolon/django-fastdrf/blob/main/docs/commands.md)).

## Guarantees and limits

- No Django or DRF class is replaced, patched or monkeypatched. fastdrf's
  classes are subclasses and mixins that a project selects.
- Everything is opt-in. With the default settings, fastdrf's serializer bases
  behave as DRF's.
- In strict parity, compiled output equals DRF's output; a field, value or
  hook the compiler cannot prove equal keeps the serializer, or that one
  source, on DRF. Input recognition never produces an error of its own.
- Synchronous only: no ORM call becomes asynchronous, and transactions,
  authentication, permissions, throttling and pagination are DRF's and
  Django's.
- Schema serializers, `fast` parity and the msgspec renderer have their own
  documented output and validation rules; they are not DRF-identical by
  design.
- A serializer instance belongs to one request; do not share it between
  threads.

See [architecture](https://github.com/ctolon/django-fastdrf/blob/main/docs/architecture.md)
for how the caches are bounded and invalidated, and for the deliberate
differences.

## Compatibility

| Django | DRF | Python |
| --- | --- | --- |
| 5.2 | 3.16, 3.17, 3.18 | 3.12, 3.13, 3.14 |
| 6.0 | 3.17, 3.18 | 3.12, 3.13, 3.14 |
| 6.1 | 3.18 | 3.12, 3.13, 3.14 |

The test suite also runs on free-threaded Python 3.14t (Django 6.1,
DRF 3.18) and at the declared minimum versions (Django 5.2, DRF 3.16,
msgspec 0.19, pydantic 2.9). `FETCH_MODE` needs Django 6.1.

## Documentation

- [Documentation index](https://github.com/ctolon/django-fastdrf/blob/main/docs/README.md)
- [Configuration reference](https://github.com/ctolon/django-fastdrf/blob/main/docs/configuration.md)
- [Example project](https://github.com/ctolon/django-fastdrf/blob/main/examples/blog/README.md):
  the same API with plain DRF and with fastdrf, with parity tests and a
  measurement script
- [Changelog](https://github.com/ctolon/django-fastdrf/blob/main/CHANGELOG.md)
- [Contributing](https://github.com/ctolon/django-fastdrf/blob/main/CONTRIBUTING.md)
- [Security policy](https://github.com/ctolon/django-fastdrf/blob/main/SECURITY.md)

## License

BSD 3-Clause. See
[LICENSE](https://github.com/ctolon/django-fastdrf/blob/main/LICENSE) and
[NOTICE](https://github.com/ctolon/django-fastdrf/blob/main/NOTICE): the optimizations derive from the aiodrf project, and the list-construction protocol from Django REST framework.
