What's new
File uploads
request.FILES
in non-POST request - basically there is a long story where Django does not set request.FILES for methods like PUT, PATCH
Users were just struggling to understand why their API endpoints are not validating and had to add special middleware that fixes that
Now django ninja will automatically notify user in that case and will ask to add that middleware when user uses non-POST methods
Pagination
- Inproved performance for async views with pagination
- PageNumberPagination support page_size (DRF similarity)
Validation errors
Requests that fail validation raise ninja.errors.ValidationError
(not to be confused with pydantic.ValidationError
).
ValidationError
s have a default exception handler that returns a 422 (Unprocessable Content) JSON response of the form:
{
"detail": [ ... ]
}
Error context
Now you can customise it by overwriting the following method:
class CustomNinjaAPI(NinjaAPI):
def validation_error_from_error_contexts(self, error_contexts): ...
pattern= Support
Regex pattern fully compatible with latest pydantic, allows you to add extra validation in arguments:
@router.get("/path/param-pattern/{item_id}")
def get_path_param_pattern(request, item_id: str = Path(..., pattern="^foo")):
return item_id
Custom Django model fields
there is now a standard way to register custom django field to pydantic type:
from ninja.orm import register_field
register_field("MyCustomField", int)
Throttling
Throttling now supports multi-period intervals, such as 5/30s
, 10/5m
, and 100/2h
. Previously, the throttling implementation only allowed single-period intervals (e.g., 5/s
, 100/d
), which limited the granularity and flexibility of rate limits.
Full Changelog
- Fix for request.FILES Population on Non-POST Methods by @vitalik in #1423
- Improve Performance for Async Pagination by @tim-hub in #1414
- PageNumberPagination support page_size as API param by @zhaozigu in #1426
- Allow Customizing Validation Errors by @jceipek in #1380
- Add pattern support to param by @sunfkny in #1336
- Operation default options, addresses #1267 by @Ksauder in #1268
- Add IPNetwork and Url serialisation by @grigi in #1349
- add register_type public function by @vitalik in #1352
- Distinguish between AuthenticationError and AuthorizationError by @c4ffein in #1257
- Add method to check is user either staff or superuser. by @adambirds in #1409
- Support multi-period intervals in throttling by @robhudson in #1373
- Add query parameters in request_params for testing by @zhaozigu in #1422
- fix - schema crashes when paginated and from future import annotations by @vitalik in #1425
- Ensure router auth always overrides api auth by default by @vitalik in #1427
- Fix of TypeError when returning None in AuthBase.call from async code #1386 by @mmkhitaryan in #1387
Tests
- Fixed coverage on Python>=3.11 by @c4ffein in #1276
- Update code with
make fmt
and the pipeline to use the same--preview
option of Ruff by @c4ffein in #1274 - CI: Use Ubuntu 22 for 3.7 support in tests by @pmdevita in #1408
Docs
- Made TestClient accept COOKIES + documentation by @c4ffein in #1311
- Better csrf doc by @c4ffein in #1314
- fix small typo in throttling docs by @noahgorstein in #1316
- Small typo fixes and doc mention router import by @michaelg100 in #1317
- document how to use an optional file input by @toudi in #1326
- fix typos in docs by @ahmetveburak in #1333
- Adding docs how to add a user in a test by @pinguin999 in #1341
- Replace update_forward_refs with model_rebuild in docs by @Danie-1 in #1366
- Updated docs for url parameters in nested routers by @kentrh in #1365
- fix spelling error in pagination.md by @syre in #1287
- Update LICENSE, fix copyright license year by @JasonnnW3000 in #1379
New Contributors
- @Ksauder made their first contribution in #1268
- @syre made their first contribution in #1287
- @michaelg100 made their first contribution in #1317
- @toudi made their first contribution in #1326
- @ahmetveburak made their first contribution in #1333
- @sunfkny made their first contribution in #1336
- @pinguin999 made their first contribution in #1341
- @grigi made their first contribution in #1349
- @Danie-1 made their first contribution in #1366
- @robhudson made their first contribution in #1373
- @kentrh made their first contribution in #1365
- @JasonnnW3000 made their first contribution in #1379
- @jceipek made their first contribution in #1380
- @adambirds made their first contribution in #1409
- @pmdevita made their first contribution in #1408
- @zhaozigu made their first contribution in #1422
- @tim-hub made their first contribution in #1414
- @mmkhitaryan made their first contribution in #1387
Full Changelog: v1.3.0...v1.4.0b1