Creating decorator

We have created three functions ( student_test_function, teacher_test_function, principal_test_function ) which return True if the user is the following user in each case. These test_functions are to be used by decorators. 

  • student_access_only decorator: It wraps a view, if the currently logged-in user is not a student then he is returned a HttpResponse, that you are not a student and you cannot access the page. 
  • teacher_access_only decorator: It requires the input view_to_return, to which the user will be redirected if they are not teachers (we will generate the URLs).
  • principal_access_only decorator: it takes a message which will be sent to a certain page telling that you are not a principal and you cannot access the page and then you will be redirected to the login page. 

Python3




from functools import wraps
from django.contrib import messages
from django.shortcuts import redirect
from django.http import HttpResponse
 
 
def student_test_function(user):
    if user.is_student:
        return True
    return False
 
 
def teacher_test_function(user):
    if user.is_teacher:
        return True
    return False
 
 
def principal_test_function(user):
    if user.is_principal:
        return True
    return False
 
 
def student_access_only():
    def decorator(view):
        @wraps(view)
        def _wrapped_view(request, *args, **kwargs):
            if not student_test_function(request.user):
                return HttpResponse("You are not a student and \
                        you are not allowed to access this page !")
            return view(request, *args, **kwargs)
        return _wrapped_view
    return decorator
 
 
def teacher_access_only(view_to_return="user_urls:home-page"):
    def decorator(view):
        @wraps(view)
        def _wrapped_view(request, *args, **kwargs):
            if not teacher_test_function(request.user):
                messages.error(request, "You cannot access \
                                the teachers  page !")
                return redirect(view_to_return)
            return view(request, *args, **kwargs)
        return _wrapped_view
    return decorator
 
 
def principal_access_only(message_to_deliver="Not allowed to \
            access the principal's page , login as principal !"):
    def decorator(view):
        @wraps(view)
        def _wrapped_view(request, *args, **kwargs):
            if not principal_test_function(request.user):
                messages.error(request, message_to_deliver)
                return redirect("user_urls:login-user")
            return view(request, *args, **kwargs)
        return _wrapped_view
    return decorator


Step 9: user/views.py

We have four views that just render out the templates.

Python3




from django.shortcuts import render
from .decorators import (
    student_access_only,
    teacher_access_only,
    principal_access_only
)
 
 
def homePage(request, *args, **kwargs):
    context = {}
    return render(request, "user/homePage.html", context)
 
 
@student_access_only()
def studentView(request, *args, **kwargs):
    context = {}
    return render(request, "user/studentView.html", context)
 
 
@teacher_access_only()
def teacherView(request, *args, **kwargs):
    context = {}
    return render(request, "user/teacherView.html", context)
 
 
@principal_access_only()
def principalView(request, *args, **kwargs):
    context = {}
    return render(request, "user/principalView.html", context)


Step 10: user/urls.py

These URLs help to route to the respective views. 

Python3




from django.urls import path
from user import views as user_views
from django.contrib.auth.views import LoginView
 
app_name = "user_urls"
 
urlpatterns = [
    path("", user_views.homePage, name="home-page"),
    path("login-user/", LoginView.as_view(template_name="user/loginView.html"),
         name="login-user"),
    path("student-view/", user_views.studentView, name="student-view"),
    path("teacher-view/", user_views.teacherView, name="teacher-view"),
    path("principal-view/", user_views.principalView, name="principal-view"),
]


Step 11: CustomDecorator/settings.py

Also, set up the LOGIN_REDIRECT_URL for the login in settings.py

Python3




LOGIN_REDIRECT_URL = "user_urls:home-page"


Step 12: CustomDecorator/urls.py

Now set up the project urls.py to direct them to our user app.

Python3




from django.contrib import admin
from django.urls import path, include
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("user.urls", namespace="user_urls")),
]


Step 13: Now, migrate the data to the database using the following command.  

python manage.py makemigrations
python manage.py migrate

Step 14: Open the Django shell and create three users, one student, one teacher, and one principal.

python manage.py shell

from user.models import UserAccount

UserAccount.objects.create_student(username = “student” , email = “studentmail@gmail.com” , password = “testing123”)

UserAccount.objects.create_teacher(username = “teacher” , email = “teachermail@gmail.com” , password = “testing123”)

UserAccount.objects.create_principal(username = “principal” , email = “principalmail@gmail.com” , password = “testing123”)

Step 19: Now run the server to test your project.

python manage.py runserver

Output:

 



Creating Custom Decorator in Django for different permissions

Decorators are incredibly helpful tools that allow you to dynamically change the functionality of a function, method, or class without having to utilize subclasses directly or modify the function’s source code. The decorator’s login_required, require HTTP methods, require POST, and others are needed when working with Django views.

But there are also situations where we want to utilize our own, uniquely designed decorators that function exactly how we want them to. Making decorators can also be useful if you apply the same logic in several places and find that it is simple to remove and add the decorator after your changes are complete.

Similar Reads

Create Custom Decorator in Django

Here, we’ll set up a mechanism for students to access the site. In order to prevent students, teachers, and principals from accessing the pages that are available to other users. These privileges will be managed by the custom decorators we will create, and we will return various results/responses on each page access so that we can see various ways you can redirect or return a response for not accessible page....

Understanding the concept of decorators for this Project

...

Creating decorator

...