django-policy-tree
Permissions for Django projects whose users belong to a tree of organizational units, with rules that superusers edit in the admin.
Any hierarchy works. You name the levels, you name the roles, you point your models at the tree:
| Domain | Tree | Roles |
|---|---|---|
| Company | Head office → Region → Branch → Team | admin, manager, member, viewer |
| Retail | Chain → Region → Store | owner, area manager, store manager, cashier |
| Healthcare | Hospital group → Hospital → Department → Ward | administrator, head nurse, doctor, nurse |
| SaaS | Tenant → Workspace → Project | owner, admin, editor, guest |
| Government | Ministry → Agency → Office | director, officer, clerk |
| Education | School → Campus → Department | admin, registrar, professor, student |
Wherever a user's role in a unit decides what they can do, django-policy-tree answers "can this user do this, to this record, and with which fields?" from one place, for lists, objects, creates, updates and fields alike.
class Project(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE) # the record's place in the tree
name = models.CharField(max_length=100)
budget = models.DecimalField(max_digits=12, decimal_places=2)
class ProjectViewSet(PolicyQuerysetMixin, viewsets.ModelViewSet):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
permission_classes = [PolicyPermission]
With the policy "managers may update projects, scope tree", a manager of the North region sees only projects in North and the branches and teams below it, can't create or edit projects anywhere else, and can't move a project out of North. Add "members may read projects, but not the budget field" and the field disappears from their responses.
Features
- Default deny, with allow and deny policies; deny wins
- Scopes:
org,tree,below,ancestors,siblings,own, and your own - Conditions written in code, picked per policy, checked before and/or after a change
- Roles in code or managed by superusers in the admin, with inheritance
- Field rules per record, on the way in and out
- DRF (permission class, viewset and serializer mixins), plain Django views, a template tag, and an engine for everything else
- Audit log, policies and roles as JSON in git, system checks
- Works with UUID primary keys and soft delete
Install
pip install "django-policy-tree[drf]"
INSTALLED_APPS = [..., "rest_framework", "policytree", "core"]
POLICYTREE_ORGANIZATION_MODEL = "core.Organization"
POLICYTREE_MEMBER_MODEL = "core.Member"
Then follow the Quickstart.
Documentation
- Quickstart
- Concepts: organizations, members and roles, policies, scopes, conditions, fields
- Guides: DRF, plain views, engine, UUIDs and soft delete, operations
- Recipes, one per domain: company, retail, healthcare, SaaS, education
- Security · Performance · Changelog
Build the docs site with pip install mkdocs-material && mkdocs serve.
Status
0.1: the API is intended to be the 1.0 API. Tested on Django 4.2, 5.2 and 6.1 with Python 3.10+, on SQLite, PostgreSQL and MariaDB, with property-based tests and an independent security review. It has not yet run in production; read Security before relying on it.
Development
pip install -e ".[test]"
pytest # SQLite
DB=postgres pytest # see tests/settings.py
DB=mysql pytest
pytest benchmarks -q -s # timings
mkdocs build --strict # docs
tests/testapp holds the test fixtures. They model one sample domain so the tests read naturally; nothing in the package depends on it. See CONTRIBUTING.md.
License
MIT
Metadata
Release files for django-policy-tree 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| django_policy_tree-0.1.0.tar.gz | 70.1 kB | With provenance | Details for django_policy_tree-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| django_policy_tree-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for django_policy_tree-0.1.0-py3-none-any.whl |
Total release size: 120.1 kB
Release files / django_policy_tree-0.1.0.tar.gz
| Download URL | django_policy_tree-0.1.0.tar.gz |
|---|---|
| Size | 70.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a2a8a129624cd384bfafb03f76c46f4baef2c44cca1364bc68e3b80b195645fe
|
|
BLAKE2b-256 checksum How to use checksums |
d3303723cd09b6f440c70561a8591687afb23667789b78e35dbbf2a337be1957
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.
Transparency logRelease files / django_policy_tree-0.1.0-py3-none-any.whl
| Download URL | django_policy_tree-0.1.0-py3-none-any.whl |
|---|---|
| Size | 50.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02092457581c62b8adc301dd91ea711ecf5827739dbad0609342959d884b45a0
|
|
BLAKE2b-256 checksum How to use checksums |
3de62cce8f317925578364c11c7e056426b2fd6377901f4e99fe870f47e8ae57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.
Transparency logSecurity for django-policy-tree 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for django_policy_tree-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.