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()