Permissions and Access Control
djxi provides a lightweight permission system that runs before any battery
endpoint handler. It requires no external packages and integrates naturally
with Django’s request.user.
Quick start — requiring authentication
Set requires_auth = True on the battery. Anonymous (unauthenticated)
users receive a 403 Forbidden response:
from djxi import DXEndpointBattery, dx_get, dx_delete
class SecureBattery(DXEndpointBattery):
inline_template = "..."
requires_auth = True
@dx_get("data/", name="data")
def data(self, request):
return self.render_section(request, "data", {"rows": fetch_rows()})
Redirecting to a login page
Set login_url alongside requires_auth to redirect unauthenticated
users instead of returning a 403:
class SecureBattery(DXEndpointBattery):
inline_template = "..."
requires_auth = True
login_url = "/accounts/login/"
@dx_get("data/", name="data")
def data(self, request):
...
The redirect uses Django’s django.shortcuts.redirect and returns a 302.
Fine-grained control with check_permissions()
Override check_permissions(self, request) for any logic beyond a simple
authentication check. Return None to allow the request through or return
any HttpResponse to short-circuit the handler:
from django.http import HttpResponseForbidden
class StaffOnlyBattery(DXEndpointBattery):
inline_template = "..."
def check_permissions(self, request):
if not getattr(request.user, "is_staff", False):
return HttpResponseForbidden("Staff only.")
return None # allow through
@dx_get("admin-data/", name="admin-data")
def admin_data(self, request):
...
Using Django’s permission system:
from django.http import HttpResponseForbidden
class PermissionedBattery(DXEndpointBattery):
inline_template = "..."
REQUIRED_PERM = "myapp.change_item"
def check_permissions(self, request):
if not request.user.has_perm(self.REQUIRED_PERM):
return HttpResponseForbidden()
return None
@dx_put("item/<int:pk>/", name="update")
def update(self, request, pk):
...
How it works
check_permissions() is defined on DXRouterMixin and called inside
every view wrapper generated by url_patterns() — before the handler
method runs. This applies to both sync and async def handlers.
The default implementation in DXEndpointBattery honours requires_auth
and login_url; if you override it you can call super() to keep that
behaviour and layer your own logic on top:
class CombinedBattery(DXEndpointBattery):
requires_auth = True
login_url = "/login/"
def check_permissions(self, request):
# First, enforce authentication (from super)
result = super().check_permissions(request)
if result is not None:
return result
# Then, add a custom rule
if request.user.profile.is_suspended:
return HttpResponseForbidden("Account suspended.")
return None
Class attribute reference
Attribute |
Default |
Description |
|---|---|---|
|
|
When |
|
|
URL to redirect unauthenticated users to. When |
Method reference
- DXEndpointBattery.check_permissions(self, request)
Called before every endpoint handler.
- Parameters:
request – The incoming
HttpRequest.- Returns:
Noneto allow the request through, or anHttpResponseto short-circuit the handler (e.g.HttpResponseForbidden()orredirect("/login/").