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 model
- disable_rls()- Disable RLS for this model
- get_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 policy
- operation(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 name
- user_field(str) - Name of the foreign key field to User model
- operation(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 name
- tenant_field(str) - Name of the foreign key field to tenant model
- operation(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 name
- expression(str) - SQL boolean expression
- operation(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 value
- is_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 table
- disable_rls(model)- Disable RLS on model's table
- force_rls(model)- Force RLS (even for table owner)
- create_policy(model, policy)- Create a policy
- drop_policy(model, policy_name)- Drop a policy
- alter_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 RLS
- as_user(user)- Context manager to set user context
- with_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}")