BudiBadu Logo
Samplebadu

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.