Django by Example: User Permission Rules
Django 5.0+
Django has a built-in permission system. This example shows how to check permissions in views using decorators and mixins, and how to check them in templates.
Code
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.views.generic import CreateView
from django.http import HttpResponse
# 1. Function-Based View Decorators
@login_required
def my_profile(request):
return HttpResponse("You are logged in")
@permission_required('blog.add_article', raise_exception=True)
def create_article(request):
# Only users with 'add_article' permission can see this
return HttpResponse("Article Created")
# 2. Class-Based View Mixins
class ArticleCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
model = Article
fields = ['title', 'content']
# Permission required
permission_required = 'blog.add_article'
# Where to go if not logged in
login_url = '/login/'
# If logged in but no permission, raise 403 Forbidden
raise_exception = True
# 3. Checking in Code
def custom_check(request):
if request.user.has_perm('blog.delete_article'):
return HttpResponse("You can delete")
else:
return HttpResponse("Access Denied", status=403)
# --- Usage in Template ---
# {% if perms.blog.add_article %}
# <a href="/create/">New Article</a>
# {% endif %}Explanation
Authentication identifies who a user is; Authorization determines what they can do. Django's permission system assigns permissions (like app.action_model) to Users or Groups.
To protect views, you use Decorators (for functions) or Mixins (for classes). If a user fails the check, they are redirected to the login page (if not logged in) or shown a 403 Forbidden error (if logged in but unauthorized).
Permissions are created automatically for every model: add, change, delete, and view.
Code Breakdown
7
@login_required. The simplest protector. If the user is anonymous, it redirects them to settings.LOGIN_URL, appending ?next=/current/path/ so they can return after logging in.11
@permission_required('app.perm'). Checks for a specific permission. raise_exception=True means show a 403 error page instead of redirecting to login if the check fails.17
LoginRequiredMixin. Must be the first class inherited (left-most) in Python's MRO to ensure it runs before other mixins or the base view logic.32
request.user.has_perm(). The manual way to check permissions inside a view function. Useful for complex logic where a simple decorator isn't enough.
