Install & Compatibility
Where this runs
tested against v3.4.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 67.8MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 3.5s · import 0.000s · 68MB
67MB installed
● package 67MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
assign_perm
✓ from guardian.shortcuts import assign_perm
✗ from guardian.shortcuts import assign_perm
get_perms
✓ from guardian.shortcuts import get_perms
get_objects_for_user
✓ from guardian.shortcuts import get_objects_for_user
This quickstart demonstrates the core functionality of `django-guardian`: setting up the `ObjectPermissionBackend`, assigning per-object permissions using `assign_perm`, checking permissions with `has_perm`, and retrieving objects a user has specific permissions for using `get_objects_for_user`.
import os
from django.conf import settings
from django.contrib.auth.models import User
from guardian.shortcuts import assign_perm, get_objects_for_user
# Minimal Django settings setup for demonstration
if not settings.configured:
settings.configure(
INSTALLED_APPS=[
'django.contrib.auth',
'django.contrib.contenttypes',
'guardian',
'myapp' # assuming a minimal app that defines a 'Book' model
],
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
AUTHENTICATION_BACKENDS=(
'django.contrib.auth.backends.ModelBackend',
'guardian.backends.ObjectPermissionBackend',
),
ANONYMOUS_USER_NAME = 'AnonymousUser', # Important for anonymous user support
SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-dev'),
DEBUG=True
)
# In a real project, this would be in models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=255)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='authored_books', null=True)
def __str__(self):
return self.title
class Meta:
permissions = (
('view_book', 'Can view book'),
('edit_book', 'Can edit book'),
)
# --- Example Usage ---
# Assume database is set up and migrations run (e.g., via `./manage.py migrate`)
# This is a simplified representation for demonstration.
# Create users and an object
user1 = User.objects.create_user(username='alice', password='password123')
user2 = User.objects.create_user(username='bob', password='password123')
book1 = Book.objects.create(title='The Great Adventure', author=user1)
book2 = Book.objects.create(title='Python Mastery', author=user2)
print(f"\nBook 1: {book1.title} by {book1.author}")
print(f"Book 2: {book2.title} by {book2.author}")
# Assign 'view_book' permission to user1 for book1
assign_perm('view_book', user1, book1)
print(f"\nAssigned 'view_book' to {user1.username} for {book1.title}")
# Check permissions
print(f"{user1.username} can view book1: {user1.has_perm('view_book', book1)}")
print(f"{user2.username} can view book1: {user2.has_perm('view_book', book1)}")
# Assign 'edit_book' permission to user1 for book2
assign_perm('edit_book', user1, book2)
print(f"Assigned 'edit_book' to {user1.username} for {book2.title}")
# Get objects user1 has 'view_book' permission for
user1_viewable_books = get_objects_for_user(user1, 'view_book', klass=Book)
print(f"\n{user1.username} can view: {[b.title for b in user1_viewable_books]}")
# Get objects user1 has 'edit_book' permission for
user1_editable_books = get_objects_for_user(user1, 'edit_book', klass=Book)
print(f"{user1.username} can edit: {[b.title for b in user1_editable_books]}")
guardian --version
Debug
Known issues
gotchaYou MUST add `guardian.backends.ObjectPermissionBackend` to your `AUTHENTICATION_BACKENDS` setting for `django-guardian` to function correctly. This is a common oversight.fixAdd `'guardian.backends.ObjectPermissionBackend'` to your `AUTHENTICATION_BACKENDS` tuple in `settings.py`. Ensure it's listed after `django.contrib.auth.backends.ModelBackend` if you still want default Django authentication.
affects: All versions
deprecatedThe `guardian.decorators.permission_required` decorator is deprecated in favor of `guardian.decorators.api_permission_required` or, for class-based views, using `guardian.mixins.ObjectPermissionRequiredMixin` or `guardian.mixins.PermissionRequiredMixin`.fixFor function-based API views, use `api_permission_required`. For class-based views, inherit from `ObjectPermissionRequiredMixin` (for all Django versions) or `PermissionRequiredMixin` (for Django 4.0+ projects).
affects: >=3.1.2
gotchaWhen using Django 4.0+ with `django-guardian`, you should use `guardian.mixins.PermissionRequiredMixin` for object-level permission checks in class-based views. Do not confuse it with Django's built-in `django.contrib.auth.mixins.PermissionRequiredMixin`, which only handles model-level permissions.fixAlways import `PermissionRequiredMixin` from `guardian.mixins` for object-level permission requirements in views.
affects: >=3.1.0 (with Django >= 4.0)
gotchaVersion 3.1.0 introduced significant database indexing improvements. While migrations are designed to run automatically, users with large permission tables should be aware of potential re-indexing operations that could temporarily impact database performance during deployment of this version or later.fixEnsure database backups are performed before migrating to 3.1.0 or later on production systems. Monitor database performance during and after applying migrations.
affects: >=3.1.0
gotchaFor anonymous user support, ensure `ANONYMOUS_USER_NAME` is configured in `settings.py`. By default, `django-guardian` uses 'AnonymousUser'. If you customize your anonymous user, `GUARDIAN_GET_INIT_ANONYMOUS_USER` might also need configuration.fixAdd `ANONYMOUS_USER_NAME = 'YourCustomAnonymousUserName'` to `settings.py` if your anonymous user is named differently. Consider `GUARDIAN_GET_INIT_ANONYMOUS_USER` if you need a custom anonymous user object initialization.
affects: All versions
Upgrade
Version history
3.4.0latest on PyPI · released Aug 28, 2026
Audit
Dependencies
DjangorequiredCore framework dependency, version compatibility is crucial. Requires Django >= 3.2.