Skip to content

Permissions & Groups ​

Django's authentication system includes a robust authorization framework. By default, Django automatically creates four permissions (add, change, delete and view) for every model you create.

Custom Permissions in Model Meta ​

You can define additional permissions for a model by using the permissions attribute within the model's Meta class. This is useful for application-specific logic that doesn't fit the standard CRUD operations.

python
from django.db import models

class Task(models.Model):
    title = models.CharField(max_length=100)
    status = models.CharField(max_length=20)

    class Meta:
        permissions = [
            ("can_publish_task", "Can publish tasks to production"),
            ("can_assign_task", "Can reassign tasks to other users"),
        ]

WARNING

After adding custom permissions to Meta, you must run python manage.py makemigrations and python manage.py migrate to create these permissions in the database.

Checking Permissions ​

Permissions are identified by a string combining the app label and the permission codename: app_label.codename.

In Code ​

Use the has_perm() method on a User object.

python
if request.user.has_perm("myapp.can_publish_task"):
    # Allow the action
    pass

In Templates ​

Access the perms object provided by the authentication context processor.

html
{% if perms.myapp.can_publish_task %}
    <button>Publish Task</button>
{% endif %}

Protecting Views ​

You can restrict view access using decorators for function views or mixins for class-based views.

python
from django.contrib.auth.decorators import permission_required

@permission_required("myapp.can_publish_task", raise_exception=True)
def publish_task(request, pk):
    # View logic here...
    pass
python
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic import UpdateView

class PublishTaskView(PermissionRequiredMixin, UpdateView):
    permission_required = "myapp.can_publish_task"
    # Will raise a 403 Forbidden if the user lacks the permission
    raise_exception = True 
    # ...

Groups ​

Groups provide a convenient way to apply multiple permissions to a set of users at once. Instead of assigning permissions to each user individually, you can group them into roles (e.g., "Editors", "Managers").

Managing Groups in Code ​

You can programmatically create groups and assign users to them using the Group model.

python
from django.contrib.auth.models import Group, User, Permission
from django.contrib.contenttypes.models import ContentType
from myapp.models import Task

# 1. Create a group
manager_group, created = Group.objects.get_or_create(name="Managers")

# 2. Add permissions to the group
content_type = ContentType.objects.get_for_model(Task)
permission = Permission.objects.get(
    codename="can_publish_task",
    content_type=content_type,
)
manager_group.permissions.add(permission)

# 3. Add a user to the group
user = User.objects.get(username="alice")
user.groups.add(manager_group)

A user inherits all permissions granted to all of the groups they belong to.

Assigning Permissions to Users ​

While groups are the recommended way to manage permissions at scale, you can also assign permissions directly to individual users using the user_permissions manager.

python
from django.contrib.auth.models import User, Permission
from django.contrib.contenttypes.models import ContentType
from myapp.models import Task

user = User.objects.get(username="alice")

# Fetch the permission object
content_type = ContentType.objects.get_for_model(Task)
permission = Permission.objects.get(
    codename="can_publish_task",
    content_type=content_type,
)

# Assign the permission to the user
user.user_permissions.add(permission)

# Other available methods:
# user.user_permissions.remove(permission)
# user.user_permissions.clear()