Skip to content

View Decorators

Django Ninja AIO provides decorator utilities for composing view behavior and attaching decorators to CRUD operations declaratively.

  • decorate_view


    Compose multiple decorators on sync/async views

  • extra_decorators


    Declarative per-operation decorators on ViewSets

  • M2M Decorators


    Custom decorators for relation endpoints

  • api_get / api_post


    Endpoint decorators with built-in decorator support


decorate_view

Compose multiple decorators into a single view wrapper.

Python
from ninja_aio.decorators import decorate_view

Behavior:

  • Order matches normal stacking: @d1 over @d2d1(d2(view))
  • Works with both sync and async views
  • None values are ignored — useful for conditional decoration
Python
from ninja_aio.decorators import decorate_view
from ninja_aio.views import APIViewSet

class MyViewSet(APIViewSet):
    api = api
    model = MyModel

    def views(self):
        @self.router.get("health/")
        @decorate_view(authenticate, log_request)
        async def health(request):
            return {"ok": True}
Python
cache_dec = cache_page(60) if settings.ENABLE_CACHE else None

@self.router.get("data/")
@decorate_view(cache_dec, authenticate)
async def data(request):
    ...

Note

decorate_view does not add an extra wrapper layer. Each decorator should preserve metadata itself (e.g., via functools.wraps).


APIViewSet.extra_decorators

Attach decorators to auto-generated CRUD operations without redefining views:

Python
from ninja_aio.schemas.helpers import DecoratorsSchema

@api.viewset(MyModel)
class MyViewSet(APIViewSet):
    extra_decorators = DecoratorsSchema(
        list=[require_auth, cache_page(30)],
        retrieve=[require_auth],
        create=[require_auth],
        update=[require_auth],
        delete=[require_auth],
    )

Available operations

Field Applies to
list GET / — List all items
retrieve GET /{pk} — Get single item
create POST / — Create item
update PATCH /{pk} — Update item
delete DELETE /{pk} — Delete item

Tip

These decorators are applied in combination with built-in decorators (unique_view, paginate) using decorate_view internally.


M2M Relation Decorators

Apply custom decorators to Many-to-Many relation endpoints via get_decorators and post_decorators:

Python
from ninja_aio.schemas import M2MRelationSchema

M2MRelationSchema(
    model=Tag,
    related_name="tags",
    get_decorators=[cache_decorator, log_decorator],   # GET (list related)
    post_decorators=[rate_limit_decorator],             # POST (add/remove)
)
Parameter Applies to
get_decorators GET /{pk}/tag — List related items
post_decorators POST /{pk}/tag — Add/remove relations

See APIViewSet M2M Relations for more details.


api_get / api_post with Decorators

Endpoint decorators accept a decorators parameter for inline decorator composition:

Python
from ninja.pagination import PageNumberPagination
from ninja_aio.decorators.operations import api_get
from ninja_aio.decorators import unique_view
from ninja.pagination import paginate

@api.viewset(models.Book)
class BookAPI(APIViewSet):
    @api_get(
        "/custom-get",
        response={200: list[GenericMessageSchema]},
        decorators=[paginate(PageNumberPagination), unique_view("test-unique-view")],
    )
    async def get_test(self, request):
        return [{"message": "This is a custom GET method in BookAPI"}]

How decorators are applied

  • Provide decorators as a list — they are applied in reverse order internally
  • paginate(PageNumberPagination) enables async pagination on the handler
  • unique_view(name) marks the route as unique to avoid duplicate registration
  • Works with @api.viewset(Model) classes extending APIViewSet

See Also

  • APIViewSet


    Complete CRUD view generation with decorator support

    Learn more

  • APIView


    Base view class for custom endpoints

    Learn more

  • Mixins


    Reusable filtering and query behaviors

    Learn more

  • Pagination


    Async pagination support for list endpoints

    Learn more