Permissions and visibility
Built-in permissions, their arguments, and field visibility.
See the Permissions guide and
Field visibility.
BasePermission
Allow everything by default; override the checks you need.
| Name |
Type |
Default |
Description |
message |
str |
gettext_noop('You do not have permission to perform this action.') |
detail of the denial response, translated with gettext when sent (so your own messages can come from your project's catalog). |
status_code |
int |
403 |
Status of the denial response (403, or 401 for authentication). |
combinator |
Literal['all', 'any', 'not'] \| None |
None |
Set by AllOf/AnyOf/Not, which evaluate operands instead of checks. |
Built-in permissions
| Class |
Arguments |
Description |
AllowAny |
— |
Allows every request. |
DenyAll |
— |
Denies every request (403). |
IsAuthenticated |
— |
Requires Ninja authentication (request.auth) or an authenticated request.user. |
IsAuthenticatedOrReadOnly |
— |
Safe methods (GET, HEAD, OPTIONS) for everyone; other methods need authentication. |
IsReadOnly |
— |
Allows safe methods only; combine it: [IsAuthenticated(), IsReadOnly() \| IsStaff()]. |
IsStaff |
— |
The user has is_staff. |
IsSuperuser |
— |
The user has is_superuser. |
HasDjangoPermission |
*perms: str |
Requires Django model permissions, e.g. HasDjangoPermission("blog.change_post"). |
DjangoModelPermissions |
model: type[Model] \| None = None, perms_map: Mapping[str, tuple[str, ...]] = field(default_factory=lambda: _DEFAULT_PERMS_MAP) |
Maps the HTTP method to the model's view/add/change/delete permissions. |
IsOwner |
field: str = 'owner' |
Object-level: obj.<field> must be the current user. |
Also |
— |
Operation permissions added to the controller's instead of replacing them. |
as_permission()
def as_permission(policy: Policy[SubjectT, ObjT], subject: type[SubjectT] | Callable[[HttpRequest], SubjectT], *, asubject: Callable[[HttpRequest], Awaitable[SubjectT]] | None = None) -> PolicyPermission[SubjectT, ObjT]: ...
Use a service-layer Policy as an object permission.
| Parameter |
Type |
Default |
Description |
policy |
Policy[SubjectT, ObjT] |
— |
An object with allows(subject, obj) -> bool. |
subject |
type[SubjectT] \| Callable[[HttpRequest], SubjectT] |
— |
The user class (the authenticated user must be one, else 401), or a function of the request. |
asubject |
Callable[[HttpRequest], Awaitable[SubjectT]] \| None |
None |
Async version of subject for async operations. |
ObjectPermissions
Per-object Django permissions by HTTP method, like DRF's DjangoObjectPermissions.
| Name |
Type |
Default |
Description |
perms_map |
Mapping[str, Sequence[str]] |
field(default_factory=lambda: dict(DEFAULT_PERMS_MAP)) |
HTTP method → permission templates (%(app_label)s, %(model_name)s). |
model_permissions |
bool |
False |
Accept model-wide Django permissions in addition to object grants. |
filter_lists |
bool |
True |
Restrict querysets to objects the caller can view (needs a filtering backend). |
hide_forbidden |
bool |
True |
Answer 404 instead of 403 when the caller cannot view the object. |
Object permission backends
| Class |
Arguments |
Description |
GrantsBackend |
— |
Object permission backend stored in ninja_devx.contrib.grants.ObjectGrant. |
GuardianBackend |
— |
django-guardian's ObjectPermissionChecker and shortcuts. |
DjangoBackend |
— |
user.has_perm(perm, obj) through AUTHENTICATION_BACKENDS; no list filtering. |
assign_perm()
def assign_perm(perm: str, holder: object, obj: Model) -> None: ...
Grant perm ("app_label.codename") to a user or group on obj.
| Parameter |
Type |
Default |
Description |
perm |
str |
— |
Full permission name, "app_label.codename". |
holder |
object |
— |
A user or a Group. |
obj |
Model |
— |
The model instance. |
remove_perm()
def remove_perm(perm: str, holder: object, obj: Model) -> None: ...
Revoke perm from a user or group on obj.
| Parameter |
Type |
Default |
Description |
perm |
str |
— |
Full permission name, "app_label.codename". |
holder |
object |
— |
A user or a Group. |
obj |
Model |
— |
The model instance. |
grants_for()
def grants_for(obj: Model) -> list[Grant]: ...
Every user and group holding permissions on obj.
| Parameter |
Type |
Default |
Description |
obj |
Model |
— |
The model instance. |
get_perms()
def get_perms(user: object, obj: Model, perms: Sequence[str]) -> list[str]: ...
The subset of perms that user holds on obj.
| Parameter |
Type |
Default |
Description |
user |
object |
— |
The user (anonymous users hold nothing). |
obj |
Model |
— |
The model instance. |
perms |
Sequence[str] |
— |
Full permission names to test. |
get_objects_for_user()
def get_objects_for_user(user: object, perms: str | Sequence[str], queryset: QuerySet[ModelT]) -> QuerySet[ModelT]: ...
Objects of queryset on which user holds every one of perms.
| Parameter |
Type |
Default |
Description |
user |
object |
— |
The user. |
perms |
str \| Sequence[str] |
— |
One or several full permission names, all required. |
queryset |
QuerySet[ModelT] |
— |
The objects to filter. |
get_backend()
def get_backend() -> ObjectPermissionBackend: ...
VisibleTo()
def VisibleTo(*permissions: BasePermission[Never], hidden: Literal['null', 'omit'] = 'null') -> None: ...
| Parameter |
Type |
Default |
Description |
*permissions |
BasePermission[Never] |
— |
All must allow; each counts as its request check and its object check. |
hidden |
Literal['null', 'omit'] |
'null' |
"null" serializes a hidden field as null; "omit" leaves it out (needs FieldVisibility). |
WriteVisibleTo()
def WriteVisibleTo(*permissions: BasePermission[Never]) -> None: ...
A field only some callers may write; checked by model controllers before persisting.
| Parameter |
Type |
Default |
Description |
*permissions |
BasePermission[Never] |
— |
All must allow the request, or the field is rejected. |
Expandable
A relation rendered as its key, or as a nested schema when the client asks.
| Name |
Type |
Default |
Description |
source |
str \| None |
None |
Attribute holding the key when not expanded (default <field>_id). |
Sensitive
Field metadata: Annotated[str, Sensitive()]. Carries no configuration;
masked by ExportMixin, mask_validation_input and AuditPrivacy. See
Operations.
sensitive_fields()
def sensitive_fields(schema: type[object]) -> frozenset[str]: ...
Field and alias names on schema annotated with Sensitive.
| Parameter |
Type |
Default |
Description |
schema |
type[object] |
— |
A pydantic model (or Schema). |
mask()
def mask(value: object) -> object: ...
Replace a sensitive value with "***" (None stays None; lists are masked element-wise).
| Parameter |
Type |
Default |
Description |
value |
object |
— |
The value to mask. |
redact_payload()
def redact_payload(schema: type[object], data: Mapping[str, object]) -> dict[str, object]: ...
A copy of data with every Sensitive field of schema masked.
| Parameter |
Type |
Default |
Description |
schema |
type[object] |
— |
The pydantic model data was (or will be) dumped from. |
data |
Mapping[str, object] |
— |
A mapping keyed by field name or alias, such as a model_dump() result. |