.. Django-Mantle documentation master file, created by
   sphinx-quickstart on Fri Sep 26 14:50:38 2025.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Django-Mantle
=============

ORM-to-Wire. Efficient validation, querying, and serialisation. Type-safe. Immutable. Fast.

Mantle:

* Allows you to move your business logic into **type-safe Python classes**,
  decoupled from the Django ORM.
* Provides automatic generation (with declarative overrides) of **efficient
  ORM queries**, including limited field fetches (``only()``/``defer()``) and
  prefetching related objects, avoiding *N+1* query problems.
* Uses a modern and **performant** approach to serialisation and validation.
* Provides a **progressive API**, with a minimal surface area by default, and depth
  when needed.

It's your type-safe layer around Django's liquid core.

Quickstart
----------

Install:

.. code-block:: bash

    pip install django-mantle

Given a Django model:

.. code-block:: python

    from django.db import models

    class Bookmark(models.Model):
        url = models.URLField(max_length=500)
        comment = models.TextField()
        favourite = models.BooleanField(default=False)

Define an attrs class as the shape for your data:

.. code-block:: python

    from attrs import define

    @define
    class BookmarkAttrs:
        url: str
        comment: str
        favourite: bool

Query into that shape:

.. code-block:: python

    from mantle import Query

    rows = Query(Bookmark.objects.all(), BookmarkAttrs).all()
    # reveal_type(rows)  # list[BookmarkAttrs]

    row = Query(Bookmark.objects.filter(favourite=True), BookmarkAttrs).get()
    # reveal_type(row)   # BookmarkAttrs

Write with validation:

.. code-block:: python

    from mantle import compose_validators, create, unique_field, update

    # Optional domain validation for create/update.
    bookmark_validator = compose_validators(
        unique_field("url"),
    )

    created = create(
        Bookmark,
        BookmarkAttrs(
            url="https://noumenal.es",
            comment="Home",
            favourite=True,
        ),
        validator=bookmark_validator,
    )
    # reveal_type(created)  # Bookmark

    updated = update(
        created,
        BookmarkAttrs(
            url="https://noumenal.es/mantle/",
            comment="Docs",
            favourite=False,
        ),
        validator=bookmark_validator,
    )
    # reveal_type(updated)  # Bookmark

Mantle builds on ``django-readers`` for efficient ORM querying, ``attrs`` for
declarative typed data classes, and ``cattrs`` for structuring and
unstructuring for serialisation.

It’s your high-performance, type-safe layer for the Django ORM that you know and love.

If you're using Django REST Framework for APIs, you can use the
`mantle-drf <https://noumenal.es/mantle-drf/>`_ add-on.


.. toctree::
    :maxdepth: 1
    :caption: Contents:

    self
    how-mantle-works
    custom-querying
    development
    changelog
