# django-guardian
[](https://github.com/django-guardian/django-guardian/actions/workflows/tests.yml)
[](https://pypi.python.org/pypi/django-guardian)
[](https://pypi.python.org/pypi/django-guardian)
[](https://djangopackages.org/packages/p/django-guardian/)
`django-guardian` is an implementation of _per-object permissions_ on top
of Django’s authorization backend. Read an introduction to per-object permissions [on djangoadvent articles](https://github.com/djangoadvent/djangoadvent-articles/blob/master/1.2/06_object-permissions.rst).
## Documentation
Online documentation is available at [https://django-guardian.readthedocs.io/](https://django-guardian.readthedocs.io/).
## Installation
To install `django-guardian` into your project run:
```bash
uv add django-guardian
```
> **TIP**: Not using a package manager like `uv` or `poetry` for your django project? You probably should try them :). In the meantime, `pip install django-guardian` works just fine too.
## Configuration
We need to hook `django-guardian` into our project.
1. Put `guardian` into your `INSTALLED_APPS` at settings module:
```python
INSTALLED_APPS = (
...
'guardian',
)
```
2. Add extra authorization backend to your `settings.py`:
```py
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'guardian.backends.ObjectPermissionBackend',
)
```
3. Create `guardian` database tables by running:
```
python manage.py migrate
```
## Usage
After installation and project hooks we can finally use object permissions
with Django.
Lets start really quickly:
```py
>>> from django.contrib.auth.models import User, Group
>>> jack = User.objects.create_user('jack', 'jack@example.com', 'topsecretagentjack')
>>> admins = Group.objects.create(name='admins')
>>> jack.has_perm('change_group', admins)
False
>>> from guardian.shortcuts import assign_perm
>>> assign_perm('change_group', jack, obj=admins)
<UserObjectPermission: admins | jack | change_group>
>>> jack.has_perm('change_group', admins)
True
```
Of course our agent jack here would not be able to _change_group_ globally:
```py
>>> jack.has_perm('change_group')
False
```
## Admin integration
Replace `admin.ModelAdmin` with `GuardedModelAdmin` for those models
which should have object permissions support within admin panel.
For example:
```py
from django.contrib import admin
from myapp.models import Author
from guardian.admin import GuardedModelAdmin
# Old way:
#class AuthorAdmin(admin.ModelAdmin):
# pass
# With object permissions support
class AuthorAdmin(GuardedModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
```
## Django Unfold integration
Users of [`django-unfold`](https://unfoldadmin.com/) will find that `guardian` is [supported out of the box via a `contrib` module](https://unfoldadmin.com/docs/integrations/django-guardian/).
Raw data
{
"_id": null,
"home_page": null,
"name": "django-guardian",
"maintainer": "Michael K., Chris Maggiuli, Bona Fide IT GmbH",
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": "Tom Clark <django-guardian@octue.com>, Brian May <brian@microcomaustralia.com.au>, Lukasz Balcerzak <lukaszbalcerzak@gmail.com>, Adam Dobrawy <guardian@jawnosc.tk>, David Graham <dpgraham4401@gmail.com>, Sezer BOZKIR <admin@sezerbozkir.com>",
"keywords": "django, permissions, authorization, object, row, level",
"author": "Chris Maggiuli, Bona Fide IT GmbH, Columbia University, SIS Development and Application Services",
"author_email": "Lukasz Balcerzak <lukaszbalcerzak@gmail.com>, Cesar Canassa <cesar.canassa@gmail.com>, Vincent Driessen <vincent@datafox.nl>, John Hensley <john@fairviewcomputing.com>, Ramanan Sivaranjan <ramanan@funkaoshi.com>, Woosuk Suh <pipoket88@gmail.com>, Bojan Mihelac <bmihelac@mihelac.org>, Rafael Ponieman <rafadev@gmail.com>, Daniel Sokolowski <daniel.sokolowski@danols.com>, Ali Lozano <alilozanoc@gmail.com>, BJ Dierkes <derks@bjdierkes.com>, Rach Belaid <rachid.belaid@gmail.com>, Michael Crosby <crosby.michael@gmail.com>, Greg Hinch <greg@greghinch.com>, Aram Dulyan <aram@dulyan.com>, Florian Hahn <flo@fhahn.com>, Piotr Kilczuk <piotr@tymaszweb.pl>, Reavis Sutphin-Gray <reavis@sutphin-gray.com>, Adri\u00e1n L\u00f3pez <adrianlopezcalvo@hotmail.com>, Jameel Al-Aziz <me@jalaziz.net>, \"John P. Neumann\" <arrantsquid@gmail.com>, Andreas Madsack <andreas@madflex.de>, Ivan Kharlamov <the.paper.men@gmail.com>, Miguel de Val-Borro <miguel.deval@gmail.com>, Jan Nakladal <mojeto1@gmail.com>, Yonel Ceruto <yceruto@abalt.org>, Luke Faraone <lfaraone@humbughq.com>, John Wegis <john@presencelearning.com>, Florentin Sardan <florentin.sardan@gmail.com>, Geoff Greer <geoff@greer.fm>, Hans Larsen <hans@hansl.ca>, \"Fabio C. Barrionuevo da Luz\" <bnafta@gmail.com>, Tomasz Wsu\u0142 <2nickers@gmail.com>, Xavier Ordoquy <xordoquy@linovia.com>, Joshua Bonnett <joshua.bonnett@gmail.com>, Jernej Kos <jernej@kos.mx>, Bruno Ribeiro da Silva <bruno@e3c.com.br>, Cezar Jenkins <emperorcezar@gmail.com>, Warren Volz <warren@warrenvolz.com>, Omer Katz <omer.drow@gmail.com>, Vishal Lal <vish61@gmail.com>, Steven DeMartini <sjd@yelp.com>, zauddelig <zauddelig@gmail.com>, Remco Wendt <remco.wendt@gmail.com>, Kevin London <kevinlondon@gmail.com>, Kouhei Maeda <mkouhei@gmail.com>, Samuel Sutch <sam@sutch.net>, Morgan Aubert <morgan.aubert@zoho.com>, Brian May <brian@microcomaustralia.com.au>, Troy Grosfield <troy.grosfield@gmail.com>, Michael Drescher <kaesemeister@gmail.com>, Verena Jaspersen <verena.jaspersen@gmail.com>, Bertrand Svetchine <bertrand.svetchine@gmail.com>, Frank Wickstr\u00f6m <frank@bambuser.com>, George Karakostas <gckarakostas@gmail.com>, Adam Dobrawy <guardian@jawnosc.tk>, Jeff Hackshaw <intrepidevio@gmail.com>, Chase Bennett <ch@se.gd>, Jonny Arnold <jonny.arnold89@gmail.com>, Davis Raymond Muro <davisraymondmuro@gmail.com>, Richard de Wit <henk.exe@gmail.com>, Pedro Rojas Gavidia <pedrorojas.gavidia@gmail.com>, Rainshaw Gao <rxg@live.com>, Tom Clark <guardian@octue.com>, Meredith Hoo <meredith.hoo1@gmail.com>, Cornelius Hoffmann <coding@volucra.de>, Sezer BOZKIR <admin@sezerbozkir.com>",
"download_url": "https://files.pythonhosted.org/packages/81/d3/436a44c7688fce1a978224c349ba66c95bf9103d548596b7a2694fd58c03/django_guardian-3.1.3.tar.gz",
"platform": null,
"description": "# django-guardian\n\n[](https://github.com/django-guardian/django-guardian/actions/workflows/tests.yml)\n[](https://pypi.python.org/pypi/django-guardian)\n[](https://pypi.python.org/pypi/django-guardian)\n[](https://djangopackages.org/packages/p/django-guardian/)\n\n`django-guardian` is an implementation of _per-object permissions_ on top\nof Django\u2019s authorization backend. Read an introduction to per-object permissions [on djangoadvent articles](https://github.com/djangoadvent/djangoadvent-articles/blob/master/1.2/06_object-permissions.rst).\n\n## Documentation\n\nOnline documentation is available at [https://django-guardian.readthedocs.io/](https://django-guardian.readthedocs.io/).\n\n\n## Installation\n\nTo install `django-guardian` into your project run:\n\n```bash\nuv add django-guardian\n```\n> **TIP**: Not using a package manager like `uv` or `poetry` for your django project? You probably should try them :). In the meantime, `pip install django-guardian` works just fine too.\n\n\n## Configuration\n\nWe need to hook `django-guardian` into our project.\n\n1. Put `guardian` into your `INSTALLED_APPS` at settings module:\n\n```python\nINSTALLED_APPS = (\n ...\n 'guardian',\n)\n```\n\n2. Add extra authorization backend to your `settings.py`:\n\n```py\nAUTHENTICATION_BACKENDS = (\n 'django.contrib.auth.backends.ModelBackend',\n 'guardian.backends.ObjectPermissionBackend',\n)\n```\n\n3. Create `guardian` database tables by running:\n\n```\npython manage.py migrate\n```\n\n## Usage\n\nAfter installation and project hooks we can finally use object permissions\nwith Django.\n\nLets start really quickly:\n\n```py\n>>> from django.contrib.auth.models import User, Group\n>>> jack = User.objects.create_user('jack', 'jack@example.com', 'topsecretagentjack')\n>>> admins = Group.objects.create(name='admins')\n>>> jack.has_perm('change_group', admins)\nFalse\n>>> from guardian.shortcuts import assign_perm\n>>> assign_perm('change_group', jack, obj=admins)\n<UserObjectPermission: admins | jack | change_group>\n>>> jack.has_perm('change_group', admins)\nTrue\n```\n\nOf course our agent jack here would not be able to _change_group_ globally:\n\n```py\n>>> jack.has_perm('change_group')\nFalse\n```\n\n## Admin integration\n\nReplace `admin.ModelAdmin` with `GuardedModelAdmin` for those models\nwhich should have object permissions support within admin panel.\n\nFor example:\n\n```py\nfrom django.contrib import admin\nfrom myapp.models import Author\nfrom guardian.admin import GuardedModelAdmin\n\n# Old way:\n#class AuthorAdmin(admin.ModelAdmin):\n# pass\n\n# With object permissions support\nclass AuthorAdmin(GuardedModelAdmin):\n pass\n\nadmin.site.register(Author, AuthorAdmin)\n```\n\n## Django Unfold integration\n\nUsers of [`django-unfold`](https://unfoldadmin.com/) will find that `guardian` is [supported out of the box via a `contrib` module](https://unfoldadmin.com/docs/integrations/django-guardian/).\n",
"bugtrack_url": null,
"license": "BSD-2-Clause",
"summary": "Per object permissions for Django",
"version": "3.1.3",
"project_urls": {
"Changelog": "https://github.com/django-guardian/django-guardian/releases",
"Documentation": "https://django-guardian.readthedocs.io/",
"Homepage": "https://github.com/django-guardian/django-guardian",
"Issues": "https://github.com/me/spam/issues",
"Repository": "https://github.com/django-guardian/django-guardian"
},
"split_keywords": [
"django",
" permissions",
" authorization",
" object",
" row",
" level"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "83fc6fd7b8bc7c52cbbfd1714673cfd28ff0b3fae32265c52d492ec0dee22cb8",
"md5": "a183b47a34f6bcf08471019f4a6971c6",
"sha256": "90e28b40eea65c326a3a961908cc300f9e1cd69b74e88d38317a9befa167b71c"
},
"downloads": -1,
"filename": "django_guardian-3.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a183b47a34f6bcf08471019f4a6971c6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 127687,
"upload_time": "2025-09-10T08:36:22",
"upload_time_iso_8601": "2025-09-10T08:36:22.533467Z",
"url": "https://files.pythonhosted.org/packages/83/fc/6fd7b8bc7c52cbbfd1714673cfd28ff0b3fae32265c52d492ec0dee22cb8/django_guardian-3.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "81d3436a44c7688fce1a978224c349ba66c95bf9103d548596b7a2694fd58c03",
"md5": "6ec396e3a72eeb27f086c18d04108905",
"sha256": "12b5e66c18c97088b0adfa033ab14be68c321c170fd3ec438898271f00a71699"
},
"downloads": -1,
"filename": "django_guardian-3.1.3.tar.gz",
"has_sig": false,
"md5_digest": "6ec396e3a72eeb27f086c18d04108905",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 93571,
"upload_time": "2025-09-10T08:36:23",
"upload_time_iso_8601": "2025-09-10T08:36:23.928321Z",
"url": "https://files.pythonhosted.org/packages/81/d3/436a44c7688fce1a978224c349ba66c95bf9103d548596b7a2694fd58c03/django_guardian-3.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-10 08:36:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "django-guardian",
"github_project": "django-guardian",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "django-guardian"
}