django-rules
Object-level permissions and rule-based authorization for Django, with no database required.
Repository Health
Technical Analysis
django-rules (imported as rules) is a tiny but powerful library that provides object-level permissions to Django without touching the database. At its core it is a generic framework for building rule-based systems out of composable predicate functions, similar to decision trees, and it can also be used standalone in non-Django contexts.
Permissions are expressed as predicates — plain callables that accept a user and an object and return True or False — which can be combined with boolean operators to build complex authorization graphs. Because rules are evaluated in memory, there are no permission tables to migrate or query, making authorization fast, testable, and easy to reason about.
What You Get
- A
@predicatedecorator that turns any callable into a composable authorization rule - Boolean operators (
&,|,^,~) for combining predicates into complex permission logic - A Django authentication backend that answers object-level
has_permchecks with no database queries - Template tags, class-based-view mixins, and DRF permission classes for wiring rules into requests
- Built-in predicate factories such as
is_group_memberand helpers for invocation context and logging
Common Use Cases
- Deciding whether a specific user may edit or delete a specific object (e.g. only a book’s author)
- Replacing Django’s row-based object permissions with fast in-memory checks
- Enforcing permissions consistently across views, templates, the admin, and REST APIs
- Building generic rule-based decision systems outside of authorization entirely
Under The Hood
Architecture - The core lives in rules/predicates.py, where the Predicate class wraps a callable that accepts zero to two positional arguments (typically user and object) and overloads Python’s bitwise operators to return new composed Predicate instances. rules/rulesets.py defines RuleSet, a dict-like mapping of string identifiers to predicates, with a shared default rule set and a separate permissions rule set consumed by rules/permissions.py’s ObjectPermissionBackend. Django’s has_perm calls flow through that backend into predicate evaluation, entirely in memory. Tech Stack - Pure Python (99.8% of the codebase) targeting Python 3.8+, with an optional Django 3.2+ integration declared in setup.py via install_requires=['Django>=3.2']. Packaging uses setuptools with a py.typed marker for type-checker support, and rules/contrib and rules/templatetags supply the Django glue. Code Quality - The project is small, black-formatted, pre-commit enabled, and ships a dedicated tests/ suite run under tox across supported Python/Django versions, with CI on GitHub Actions and coverage reporting. Naming is consistent and the public surface is deliberately compact. API Design - The @predicate decorator plus operator overloading gives an unusually ergonomic authorization DSL: rules read almost like boolean expressions, and the same predicates work across views, templates, admin, and DRF. The extensive README doubles as a tutorial, keeping the learning curve low.