API Reference
Complete API documentation for Django RLS.
Models
RLSModel
Base class for models that use Row Level Security.
from django_rls.models import RLSModel
class MyModel(RLSModel):
# Your fields here
class Meta:
rls_policies = [
# List of policies
]
Class Methods:
enable_rls()
- Enable RLS for this modeldisable_rls()
- Disable RLS for this modelget_rls_policies()
- Get list of policies defined for this model
Meta Options:
rls_policies
- List of policy instances to apply to this model
Policies
BasePolicy
Abstract base class for all policies.
from django_rls.policies import BasePolicy
class CustomPolicy(BasePolicy):
def get_sql_expression(self) -> str:
return "your SQL expression"
Parameters:
name
(str) - Unique name for the policyoperation
(str) - SQL operation: 'ALL', 'SELECT', 'INSERT', 'UPDATE', 'DELETE'permissive
(bool) - Whether policy is permissive (True) or restrictive (False)roles
(str) - PostgreSQL roles to apply to (default: 'public')
UserPolicy
Policy for user-based access control.
from django_rls.policies import UserPolicy
UserPolicy(
name='owner_policy',
user_field='owner', # Foreign key field name
operation='ALL',
permissive=True
)
Parameters:
name
(str) - Policy nameuser_field
(str) - Name of the foreign key field to User modeloperation
(str) - SQL operation (default: 'ALL')permissive
(bool) - Policy type (default: True)
TenantPolicy
Policy for tenant-based isolation.
from django_rls.policies import TenantPolicy
TenantPolicy(
name='tenant_isolation',
tenant_field='tenant', # Foreign key field name
operation='ALL',
permissive=False # Often restrictive for tenant isolation
)
Parameters:
name
(str) - Policy nametenant_field
(str) - Name of the foreign key field to tenant modeloperation
(str) - SQL operation (default: 'ALL')permissive
(bool) - Policy type (default: True)
CustomPolicy
Policy with custom SQL expression.
from django_rls.policies import CustomPolicy
CustomPolicy(
name='complex_policy',
expression="status = 'active' AND (is_public OR owner_id = current_setting('rls.user_id')::int)"
)
Parameters:
name
(str) - Policy nameexpression
(str) - SQL boolean expressionoperation
(str) - SQL operation (default: 'ALL')permissive
(bool) - Policy type (default: True)
Middleware
RLSContextMiddleware
Middleware that sets PostgreSQL session variables from request.
MIDDLEWARE = [
# ... other middleware
'django_rls.middleware.RLSContextMiddleware',
]
Behavior:
- Extracts user ID from
request.user
- Extracts tenant ID from
request.tenant
,request.user.profile.tenant_id
, orrequest.session['tenant_id']
- Sets PostgreSQL session variables using
SET LOCAL
- Clears context after request
Customization:
from django_rls.middleware import RLSContextMiddleware
class CustomRLSMiddleware(RLSContextMiddleware):
def _get_tenant_id(self, request):
# Custom tenant extraction logic
return tenant_id
def _set_rls_context(self, request):
super()._set_rls_context(request)
# Set additional context
Database Functions
set_rls_context
Set a PostgreSQL session variable for RLS.
from django_rls.db.functions import set_rls_context
set_rls_context('user_id', 123)
set_rls_context('tenant_id', 456)
set_rls_context('custom_var', 'value', is_local=True)
Parameters:
name
(str) - Variable name (without 'rls.' prefix)value
(Any) - Variable valueis_local
(bool) - Use SET LOCAL (transaction-scoped) vs SET (session-scoped)
get_rls_context
Get a PostgreSQL session variable value.
from django_rls.db.functions import get_rls_context
user_id = get_rls_context('user_id')
tenant_id = get_rls_context('tenant_id', default=None)
Parameters:
name
(str) - Variable name (without 'rls.' prefix)default
(Any) - Default value if variable not set
RLSContext
Context manager for temporarily setting RLS context.
from django_rls.db.functions import RLSContext
with RLSContext(user_id=123, tenant_id=456):
# Code executed with this context
documents = Document.objects.all()
# Context automatically cleared
Schema Editor
RLSDatabaseSchemaEditor
Extended schema editor with RLS operations.
from django_rls.backends.postgresql import RLSDatabaseSchemaEditor
with connection.schema_editor() as schema_editor:
schema_editor.enable_rls(Model)
schema_editor.create_policy(Model, policy)
Methods:
enable_rls(model)
- Enable RLS on model's tabledisable_rls(model)
- Disable RLS on model's tableforce_rls(model)
- Force RLS (even for table owner)create_policy(model, policy)
- Create a policydrop_policy(model, policy_name)
- Drop a policyalter_policy(model, policy)
- Alter existing policy
Migration Operations
EnableRLS
Migration operation to enable RLS.
from django_rls.migration_operations import EnableRLS
operations = [
EnableRLS('myapp', 'MyModel'),
]
DisableRLS
Migration operation to disable RLS.
from django_rls.migration_operations import DisableRLS
operations = [
DisableRLS('myapp', 'MyModel'),
]
CreatePolicy
Migration operation to create a policy.
from django_rls.migration_operations import CreatePolicy
from django_rls.policies import UserPolicy
operations = [
CreatePolicy(
'myapp',
'MyModel',
UserPolicy('owner_policy', user_field='owner')
),
]
DropPolicy
Migration operation to drop a policy.
from django_rls.migration_operations import DropPolicy
operations = [
DropPolicy('myapp', 'MyModel', 'policy_name'),
]
Exceptions
PolicyError
Raised when policy configuration is invalid.
from django_rls.exceptions import PolicyError
try:
policy = UserPolicy('invalid_policy', user_field='')
except PolicyError as e:
print(f"Invalid policy: {e}")
ConfigurationError
Raised when RLS configuration is invalid.
from django_rls.exceptions import ConfigurationError
try:
class BadModel(RLSModel):
class Meta:
rls_policies = "not_a_list" # Should be a list
except ConfigurationError as e:
print(f"Configuration error: {e}")
Test Utilities
RLSTestMixin
Mixin providing RLS testing utilities.
from django_rls.test import RLSTestMixin
from django.test import TestCase
class MyTest(RLSTestMixin, TestCase):
def test_something(self):
with self.disable_rls(Model):
# Test with RLS disabled
with self.as_user(user):
# Test with specific user context
with self.with_context(user_id=1, tenant_id=2):
# Test with custom context
Methods:
disable_rls(model)
- Context manager to temporarily disable RLSas_user(user)
- Context manager to set user contextwith_context(**kwargs)
- Context manager to set arbitrary context
Settings
DJANGO_RLS
Optional settings dict for Django RLS configuration.
DJANGO_RLS = {
'DEFAULT_SCHEMA_EDITOR': 'django_rls.backends.postgresql.RLSDatabaseSchemaEditor',
'CONTEXT_PROCESSOR': 'myapp.rls.custom_context_processor',
'AUTO_ENABLE_RLS': True, # Enable RLS automatically in migrations
'POLICY_NAMING_CONVENTION': '{model_name}_{policy_type}_policy',
}
Signals
pre_enable_rls
Sent before enabling RLS on a model.
from django_rls.signals import pre_enable_rls
@receiver(pre_enable_rls)
def before_enable_rls(sender, model, **kwargs):
print(f"About to enable RLS for {model}")
post_enable_rls
Sent after enabling RLS on a model.
from django_rls.signals import post_enable_rls
@receiver(post_enable_rls)
def after_enable_rls(sender, model, **kwargs):
print(f"RLS enabled for {model}")