Managing Django groups and permissions for custom users
For my Django projects, I am used to creating a custom user model and managing what my user can do for a specific route using a roles field like this:
class User(AbstractBaseUser, PermissionsMixin):
name = models.CharField("full name", max_length=255, blank=True)
email = models.EmailField("email address", unique=True)
createdAt = models.DateField(auto_now_add=True)
photo = models.ImageField(
"profile photo",
blank=True,
null=True,
validators=[
FileExtensionValidator(allowed_extensions=["jpg", "png", "jpeg"])
],
) # by default retrieves file from media root
role = models.CharField(
max_length=50,
choices=[(role.value, role.name) for role in USER_ROLES],
)
is_active = models.BooleanField(default=True)
USERNAME_FIELD = "email"
objects: CustomUserManager = CustomUserManager()
def has_perm(self, perm, obj=None):
if self.role == USER_ROLES.ADMIN.value:
return True
return super().has_perm(perm, obj)
def has_module_perms(self, app_label):
if self.role == USER_ROLES.ADMIN.value:
return True
return super().has_module_perms(app_label)
@property
def is_staff(self):
return self.role == USER_ROLES.ADMIN.value
@property
def is_superuser(self):
return self.role == USER_ROLES.ADMIN.value
def __str__(self) -> str:
return f"{self.pk}-{self.email}"
But I realize that it’s best to shift to a multi-role approach for flexibility and I was hoping to use the built-in Group and Permissions model for this. However, I was confused as to how to handle the groups and permissions for each user inside a view/API route and sync any changes in groups and permissions later on if needed. Can anyone suggest an efficient way of doing so without relying on the built-in Django Admin panel?
I thought about using Group.get_or_create every time a User is created via a view and add another view adding and updating permissions for a particular group and using group permissions to handle authorization but I am not sure if it is a good idea to do if I ever need to make user group changes.
Django has PermissionRequiredMixin which can be derived for each View. PermissionRequired mixin has class property "permission_required". So you can individually define required permission for each view. Also you can tie users to permission groups and assign multiple permissions for each group.
https://docs.djangoproject.com/en/5.2/topics/auth/default/#the-permissionrequiredmixin-mixin
https://docs.djangoproject.com/en/5.2/topics/auth/default/#groups