Authorization in Django

medium · Django

While Authentication verifies who a user is, Authorization dictates what that user is permitted to do. Django handles authorization through a built-in Role-Based Access Control (RBAC) system using Permissions and Groups . This system allows you to restrict access to specific views, database records, or UI components based on a user's assigned role. 1. Core Concepts: Permissions & Groups Permissions (The Fine-Grained Rules) Whenever you run a database migration on a new model, Django automatically generates four fine-grained, atomic permissions for that model. These permissions follow a strict naming convention: <app_label>.<action>_<modelname> . For a model named ProjectOpening inside an app named positions_board , Django creates: positions_board.add_projectopening positions_board.change_projectopening positions_board.delete_projectopening positions_board.view_projectopening You can check if a user has a specific permission using the has_perm() method: Python # Returns True if the user has explicit or inherited authorization if user.has_perm('positions_board.delete_projectopening'): print("User is authorized to purge records.") Groups (The Roles) Assigning permissions to hundreds of users individually quickly becomes unmanageable. Instead, you can use Groups to bundle permissions into logical corporate roles (e.g., "Recruiters", "Hiring Managers", "Compliance Officers"). When you add a user to a Group, they automatically inherit every permission assigned to that Group. 2. Enforcing Access in Function-Based Views (Decorators) For Function-Based Views (FBVs), Django provides a suite of Python decorators to intercept incoming requests and block unauthorized users before your view code executes. A. Checking Authentication State ( @login_required ) Redirects anonymous users to your login page instantly. Python from django.contrib.auth.decorators import login_required from django.shortcuts import render @login_required(login_url='/login/') def internal_dashboard_view(request): return render(request, 'dashboard.html') B. Checking Specific Permissions ( @permission_required ) Blocks users who lack a specific permission flag. By default, unauthorized users are redirected to the login page, but setting raise_exception=True triggers a standard 403 Forbidden error response instead. Python from django.contrib.auth.decorators import permission_required @permission_required('positions_board.delete_projectopening', raise_exception=True) def purge_listing_view(request, opening_id): # This block executes only if the user has the explicit delete permission return render(request, 'deleted_success.html') C. Checking Custom Criteria ( @user_passes_test ) When you need to restrict a view based on custom logic—such as checking if a user belongs to a specific corporate group—use @user_passes_test . It accepts a helper function that returns True or False . Python from django.contrib.auth.decorators import user_passes_test def is_hr_staff(user): # Checks if the user belongs to the 'HR Team' group array return user.groups.filter(name='HR Team').exists() @user_passes_test(is_hr_staff, raise_exception=True) def hr_payroll_portal(request): return render(request, 'payroll.html') 3. Enforcing Access in Class-Based Views (Mixins) Because you cannot attach function decorators directly to entire class objects, Class-Based Views (CBVs) enforce authorization using Mixins . Mixins are parent classes that inject validation hooks into the view's lifecycle execution loop. Critical Guardrail: Python evaluates base classes from left to right. To ensure authorization checks execute before anything else, always declare your access mixins as the very first arguments in your class definition. Python from django.views.generic import ListView from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin from .models import ProjectOpening # The view enforces login validation first, then checks permissions, and finally loads the ListView mechanics class SecureOpeningListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): model = ProjectOpening template_name = 'openings_list.html' # 1. Configure the required permission rule permission_required = 'positions_board.view_projectopening' # 2. Dictate the failure behavior path raise_exception = True 4. UI-Level Authorization (Template Layer) Restricting views protects your backend endpoints, but you should also update your front-end user interface to hide links or buttons that unauthorized users cannot use. Django's template engine automatically injects a perms variable into the context, allowing you to check user permissions directly inside your HTML layouts using standard conditional tags. HTML <div class="control-panel"> <h3>Requisition Matrix</h3> <a href="{% url 'view-openings' %}" class="btn">View Openings Ledger</a> {% if perms.positions_board.add_projectopening %} <a href="{% url 'create-opening' %}" class="btn btn-success">Add New Requisition Slot</a> {% endif %} {% if perms.positions_board.delete_projectopening %} <button class="btn btn-danger">Purge System Table Row</button> {% endif %} </div> Authorization Subsystem Engineering Matrix Tool Primitive Execution Structural Model Core Engineering Use Case Failure Resolution Action @login_required FBV Function Decorator. Restricts access to authenticated users across internal pages. Redirects anonymous clients back to the login path. @permission_required FBV Function Decorator. Restricts access to users with specific atomic database permissions. Returns a 403 Forbidden error or redirects to login. LoginRequiredMixin CBV Class Parent Mixin. Restricts class-based endpoints to authenticated accounts. Redirects anonymous clients back to the login path. PermissionRequiredMixin CBV Class Parent Mixin. Enforces granular permission checking inside generic class views. Triggers an immediate 403 Forbidden HTTP exception. perms Variable Template Engine Context. Conditionally renders or hides interactive UI elements (links, buttons). Elements are stripped out silently before the HTML is sent to the browser.

Back to Django

Browse all study material on Careeroza