Skip to content

Releases: vitalik/django-ninja

1.6.2

18 Mar 20:06
0b67d47

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.6.1...v1.6.2

1.6.1

18 Mar 13:23
f8d0a8c

Choose a tag to compare

What's Changed

Full Changelog: v1.6.0...v1.6.1

1.6.0

12 Mar 08:44
56e8687

Choose a tag to compare

What's New

Idempotent Router(s)

Routers are now reusable and can be mounted to multiple APIs or multiple times within the same API. Decorators, auth, tags, and throttle settings are fully isolated between mounts.

router = Router(tags=["shared"])

@router.get("/items")
def list_items(request):
    return [{"id": 1}]

# Mount same router to multiple APIs
api_v1 = NinjaAPI(urls_namespace="v1")
api_v1.add_router("/", router)

api_v2 = NinjaAPI(urls_namespace="v2")
api_v2.add_router("/", router) # !!! Before this was giving an error

Cursor Pagination

New CursorPagination class for stable pagination over frequently changing datasets. Uses base64-encoded cursor tokens instead of offsets, ensuring consistent results even when items are added or removed.

from ninja.pagination import paginate, CursorPagination

@api.get("/events", response=list[EventSchema])
@paginate(CursorPagination, ordering=("-created",), page_size=20)
def list_events(request):
    return Event.objects.all()

Status Return

New Status class for explicitly returning HTTP status codes. Replaces the old tuple syntax (status_code, body) which is now deprecated.

from ninja import Status

@api.post("/login", response={200: Token, 401: Message})
def login(request, payload: Auth):
    if not valid:
        return Status(401, {"message": "Unauthorized"})
    return Status(200, {"token": token})

Skip Re-validation

When returning a Pydantic model instance that already matches the response schema, Django Ninja now skips redundant validation and directly serializes — a nice performance boost.

@api.get("/user", response=UserOut)
def get_user(request):
    return UserOut(id=1, name="John")  # skips re-validation

Streaming Responses (JSONL & SSE)

First-class streaming support with automatic schema validation for each chunk. Supports both JSONL and Server-Sent Events formats.

from ninja.streaming import JSONL, SSE

@api.get("/items", response=JSONL[Item])
def stream_items(request):
    for i in range(100):
        yield {"name": f"item-{i}", "price": float(i)}

@api.get("/events", response=SSE[Item])
async def stream_events(request):
    async for item in get_items():
        yield item

Details

New Contributors

Full Changelog: v1.5.3...v1.6.0

1.6.0 beta1

06 Mar 14:12
e6f732b

Choose a tag to compare

1.6.0 beta1 Pre-release
Pre-release

Note: This is beta release which is still testing - we encorage you to test this release as well and provide feedback

What's New

Idempotent Router(s)

Routers are now reusable and can be mounted to multiple APIs or multiple times within the same API. Decorators, auth, tags, and throttle settings are fully isolated between mounts.

router = Router(tags=["shared"])

@router.get("/items")
def list_items(request):
    return [{"id": 1}]

# Mount same router to multiple APIs
api_v1 = NinjaAPI(urls_namespace="v1")
api_v1.add_router("/", router)

api_v2 = NinjaAPI(urls_namespace="v2")
api_v2.add_router("/", router) # !!! Before this was giving an error

Cursor Pagination

New CursorPagination class for stable pagination over frequently changing datasets. Uses base64-encoded cursor tokens instead of offsets, ensuring consistent results even when items are added or removed.

from ninja.pagination import paginate, CursorPagination

@api.get("/events", response=list[EventSchema])
@paginate(CursorPagination, ordering=("-created",), page_size=20)
def list_events(request):
    return Event.objects.all()

Status Return

New Status class for explicitly returning HTTP status codes. Replaces the old tuple syntax (status_code, body) which is now deprecated.

from ninja import Status

@api.post("/login", response={200: Token, 401: Message})
def login(request, payload: Auth):
    if not valid:
        return Status(401, {"message": "Unauthorized"})
    return Status(200, {"token": token})

Skip Re-validation

When returning a Pydantic model instance that already matches the response schema, Django Ninja now skips redundant validation and directly serializes — a nice performance boost.

@api.get("/user", response=UserOut)
def get_user(request):
    return UserOut(id=1, name="John")  # skips re-validation

Streaming Responses (JSONL & SSE)

First-class streaming support with automatic schema validation for each chunk. Supports both JSONL and Server-Sent Events formats.

from ninja.streaming import JSONL, SSE

@api.get("/items", response=JSONL[Item])
def stream_items(request):
    for i in range(100):
        yield {"name": f"item-{i}", "price": float(i)}

@api.get("/events", response=SSE[Item])
async def stream_events(request):
    async for item in get_items():
        yield item

Details

New Contributors

Full Changelog: v1.5.3...v1.6.0b1

1.5.3

10 Jan 20:01

Choose a tag to compare

Fixed swagger css #1648

v1.5.2

04 Jan 10:13

Choose a tag to compare

A minor update

What's Changed

New Contributors

Full Changelog: v1.5.1...v1.5.2

1.5.1

04 Dec 11:35
9b7c4f1

Choose a tag to compare

What's Changed

Misc

New Contributors

Full Changelog: v1.5.0...v1.5.1

1.5.0

13 Nov 17:57
2f83e73

Choose a tag to compare

What's New

Changes

Misc

New Contributors

Chances since Beta1
Full Changelog: v1.5.0b1...v1.5.0b2

1.5.0 b2

10 Nov 19:27
22e841a

Choose a tag to compare

1.5.0 b2 Pre-release
Pre-release

What's New

Changes

Misc

New Contributors

Chances since Beta1
Full Changelog: v1.5.0b1...v1.5.0b2

1.4.5

19 Oct 18:27

Choose a tag to compare

What's Changed

  • pydantic2.12 compatibility
  • #1572 regression fix