I wanted to implement this as well, so I created my own custom mixin, just like LoginRequiredMixin.
Here’s the mixin.py code
from django.core.exceptions import PermissionDenied
from django.contrib.auth.mixins import PermissionRequiredMixin
# GroupRequiredMixin
class GroupRequiredMixin:
required_groups = []
def has_group_permissions(self):
user = self.request.user
return any(group in user.groups.values_list('name', flat=True) for group in self.required_groups)
def dispatch(self, request, *args, **kwargs):
if not self.has_group_permissions():
raise PermissionDenied()
return super().dispatch(request, *args, **kwargs)
class CustomGroupRequiredMixin(GroupRequiredMixin, PermissionRequiredMixin):
def has_permission(self):
if self.has_group_permissions():
return True
return super(PermissionRequiredMixin, self).has_permission()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# set the required_groups attribute if not already set
if not hasattr(self, 'required_groups'):
self.required_groups = []
Here’s the implementation within the view:
class MyView(LoginRequiredMixin, CustomGroupRequiredMixin, View):
required_groups = ["coaches"]
...
If you’re using method-based views it then use the mixin as a decorator.
Here’s the decorator code:
from functools import wraps
def custom_group_required(required_groups):
def decorator(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
user = request.user
if any(group in user.groups.values_list('name', flat=True) for group in required_groups):
return view_func(request, *args, **kwargs)
else:
raise PermissionDenied
return wrapper
return decorator
How you’d use it on a view.
@custom_group_required(['coaches'])
def my_view(request):
...
I also created a tag filter. Here’s the code
To create template tag filters, you should refer to this page: https://docs.djangoproject.com/en/5.0/howto/custom-template-tags/
from django import template
@register.filter(name='has_group')
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()
Here’s the HTML implementation:
{% if request.user|has_group:"coaches" %}
<th data-column="id;id" data-format="<a href='view/-id-'>View</a> | <a href='edit/-id-'>Edit</a>">Actions</th>
{% else %}
<th data-column="id" data-format="<a href='view/-id-'>View</a>">Actions</th>
{% endif %}
Let me know if you have any questions.