Last Updated : 24 May, 2025
Our task is to design the backend efficiently following the DRY (Don't Repeat Yourself) principle, by grouping users and assigning permissions accordingly. Users inherit the permissions of their groups.
Let's consider a trip booking service, how they work with different plans and packages. There is a list of product which subscriber gets on subscribing to different packages, provided by the company. Generally, the idea they follow is the level-wise distribution of different products.
Let's see the different packages available on tour booking service :
Create a Django app called users. Inside users/models.py:
Python
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
from django.db import models
class User(AbstractUser):
first_name = models.CharField(_('First Name of User'),
blank = True, max_length = 20)
last_name = models.CharField(_('Last Name of User'),
blank = True, max_length = 20)
class Meta:
permissions = (
("can_go_in_non_ac_bus", "To provide non-AC Bus facility"),
("can_go_in_ac_bus", "To provide AC-Bus facility"),
("can_stay_ac-room", "To provide staying at AC room"),
("can_stay_ac-room", "To provide staying at Non-AC room"),
("can_go_dehradoon", "Trip to Dehradoon"),
("can_go_mussoorie", "Trip to Mussoorie"),
("can_go_haridwaar", "Trip to Haridwaar"),
("can_go_rishikesh", "Trip to Rishikesh")
)
Migrate your Database
Create Groups and Assign Permissions Option A: Using Django Admin Panelpython manage.py makemigrations users
python manage.py migrate
python manage.py shell
Then run:
Python
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from users.models import User
level0, created = Group.objects.get_or_create(name='level0')
level1, created = Group.objects.get_or_create(name='level1')
level2, created = Group.objects.get_or_create(name='level2')
user_ct = ContentType.objects.get_for_model(User)
perm_haridwar, created = Permission.objects.get_or_create(
codename='can_go_haridwar',
name='Can go to Haridwar',
content_type=user_ct
)
level0.permissions.add(perm_haridwar)
Explanation:
You can add users to groups either through the Admin Panel or programmatically:
Python
from django.contrib.auth.models import Group
from users.models import User
user = User.objects.get(username='john')
group = Group.objects.get(name='level0')
user.groups.add(group)
Explanation:
Use Django's built-in permission_required decorator or create a custom group-based decorator:
Python
from django.contrib.auth.decorators import user_passes_test
def group_required(*group_names):
def in_groups(u):
if u.is_authenticated:
if bool(u.groups.filter(name__in=group_names)) or u.is_superuser:
return True
return False
return user_passes_test(in_groups)
# Usage
@group_required('level0')
def my_view(request):
# Your view logic here
...
Explanation:
Create a mixin to check group membership:
Python
from django.contrib.auth.mixins import AccessMixin
class GroupRequiredMixin(AccessMixin):
group_required = [] # List of groups allowed to access the view
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return self.handle_no_permission()
user_groups = request.user.groups.values_list('name', flat=True)
if not any(group in user_groups for group in self.group_required):
return self.handle_no_permission()
return super().dispatch(request, *args, **kwargs)
Usage:
Python
from django.views import View
class DemoView(GroupRequiredMixin, View):
group_required = ['admin', 'manager']
def get(self, request, *args, **kwargs):
# View logic
...
Explanation:
Read Next Article: Extending and customizing django-allauth
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4