Django Permissions, User Groups & Role-Based Access Control (RBAC)

Authentication answers the question: "Who are you?" Authorization answers: "What are you allowed to do?" Django provides a mature, fine-grained Role-Based Access Control (RBAC) framework based on permissions and groups.

The Anatomy of a Permission String

Django identifies permissions using an <app_label>.<action>_<modelname> notation:

  • blog.view_blogpost: Can view blog post records.
  • blog.add_blogpost: Can publish new blog posts.
  • blog.change_blogpost: Can edit existing articles.
  • blog.delete_blogpost: Can permanently remove articles.

Declaring Custom Permissions on Models

Define domain-specific permissions inside your model's Meta class:

# blog/models.py
class BlogPost(models.Model):
    title = models.CharField(max_length=200)
    # ... fields ...

    class Meta:
        permissions = [
            ("can_publish_article", "Can toggle article publication state"),
            ("can_feature_article", "Can spotlight article on homepage"),
        ]

Enforcing Permissions in Views and Templates

# In Class-Based Views:
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic import UpdateView

class ArticlePublishView(PermissionRequiredMixin, UpdateView):
    model = BlogPost
    permission_required = 'blog.can_publish_article'
    # Automatically returns 403 Forbidden or redirects to login if user lacks permission!

Inside templates, show buttons only to users who hold the permission:

<!-- templates/blog/post_detail.html -->
<h1>{{ post.title }}</h1>

{% if perms.blog.change_blogpost %}
    <a href="{% url 'blog:post_update' post.slug %}" class="btn btn-warning">Edit Article</a>
{% endif %}

{% if perms.blog.can_publish_article %}
    <button class="btn btn-success">Approve for Publication</button>
{% endif %}

Superuser Privilege

A user with is_superuser = True bypasses all permission checks — user.has_perm() will always return True regardless of what individual permissions or groups they have been assigned.

Frequently Asked Questions (FAQ) - Student & Interview Review

Q1. What four default permissions does Django generate for every model?

Django automatically generates four permissions for every model in `INSTALLED_APPS`: `add_`, `change_`, `delete_`, and `view_` (e.g. `blog.add_blogpost`, `blog.change_blogpost`).

Q2. What is a Django Group?

A Group is a category of users that share a common set of permissions. Instead of assigning permissions to hundreds of individual users one by one, you assign permissions to a Group (e.g., 'Editors', 'Moderators', 'Finance'), and add users to that group.

Q3. How do you check permissions in Python views?

Check `request.user.has_perm('app_label.codename')`. In Function-Based Views, decorate with `@permission_required('blog.change_blogpost')`. In Class-Based Views, inherit from `PermissionRequiredMixin` and set `permission_required = 'blog.change_blogpost'`.

Q4. How do you check permissions inside DTL HTML templates?

Django injects a `perms` object into templates. Use `{% if perms.blog.delete_blogpost %} {% endif %}` to selectively display administrative action buttons to authorized users.

Explore Related Django Tutorials & Next Steps

Broaden your backend architecture, REST API design, and production engineering expertise:

User Authentication & Logins

The gatekeeper foundations required before checking permissions.

Django Admin Customization

Assign staff permissions and model CRUD rights in the admin UI.

Generic Class-Based Views (CBVs)

Restrict views with PermissionRequiredMixin and UserPassesTestMixin.

Django Security Hardening

Implement least-privilege role-based access controls across your application.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!