A decorator is a function that takes another function and returns a newer, prettier version of that function.
To know more about decorators in python see here https://micropyramid.com/blog/programming-with-python-decorators/
The most common use of a decorator is the login_required, which is used in conjunction with a Django view that restricts access to authenticated users only.
from django.contrib.auth.decorators import login_required @login_required(login_url='/dashboard/') def index(request): return render(request, 'index.html')
This decorator is very useful because we don’t have to actually change anything about my view to restrict access to it.
login required takes an optional argument login_url. If a user is authenticated, it successfully executes the function,
if not it redirects the users to URL specified in the login_url option. If we don't mention login_url option, we must define login_url in settings.py
But the login_required decorator does not check when the logged in user is active or not. We can use the "user_passes_test" decorator to write our own custom decorators
from django.contrib.auth.decorators import login_required, user_passes_test user_login_required = user_passes_test(lambda user: user.is_active, login_url='/') def active_user_required(view_func): decorated_view_func = login_required(user_login_required(view_func)) return decorated_view_func @active_user_required def index(request): return render(request, 'index.html')
Here user_passes_test decorator returns the value of is_active, which is a boolean that designates if the user is active.
and login_url parameter, which will redirect to this URL if the user is not active. So we can use active_user_required decorator to
If you want to execute the view according to the user role, we can write decorators using model methods
def is_recruiter(self): if str(self.user_type) == 'Recruiter': return True else: return False rec_login_required = user_passes_test(lambda u: True if u.is_recruiter else False, login_url='/') def recruiter_login_required(view_func): decorated_view_func = login_required(rec_login_required(view_func), login_url='/') return decorated_view_func @recruiter_login_required def index(request): return render(request, 'index.html')
Here is_recruiter is a model method which checks the user role. We are using the model method in the user_passes_test decorator. If user role satisfied, then it executes the function, otherwise, it redirects the home page
If you want to execute the view according to the user permission, we can write parameterized decorators using Django permissions
We can list user permissions in the user model metaclass.
class Meta: permissions = ( ('blog_view', 'can view blog posts and categories'), ('blog_edit', 'can edit blog category and post'), ("support_view", "can view tickets"), ("support_edit", "can edit tickets"), ("activity_view", "can view recruiters, applicants, data, posts"), ("activity_edit", "can edit data"), ) def has_perm(self, perm, obj=None): try: user_perm = self.user_permissions.get(codename=perm) except ObjectDoesNotExist: user_perm = False if user_perm: return True else: return False def permission_required(*perms): return user_passes_test(lambda u: any(u.has_perm(perm) for perm in perms), login_url='/') @permission_required("activity_view", "activity_edit") def index(request): return render(request, 'index.html')
Here we can pass user permissions values in decorator itself, and in the permission_required, we are checking user is having particular permission or not using for loop. If user don't have permits, it redirects the home page.
Django-CRM :Customer relationship management based on Django
Django-blog-it : django blog with complete customization and ready to use with one click installer Edit
Django-webpacker : A django compressor tool
Django-MFA : Multi Factor Authentication
Docker-box : Web Interface to manage full blown docker containers and imagesMore...