Управление группами Django и разрешениями для пользовательских пользователей
В своих проектах на Django я привык создавать пользовательскую модель пользователя и управлять тем, что мой пользователь может делать для определенного маршрута, используя поле ролей, подобное этому:
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}"
Но я понимаю, что для обеспечения гибкости лучше всего перейти к многоцелевому подходу, и я надеялся использовать для этого встроенную модель групп и разрешений. Однако я был сбит с толку тем, как обрабатывать группы и разрешения для каждого пользователя внутри маршрута просмотра / API и синхронизировать любые изменения в группах и разрешениях позже, если потребуется. Кто-нибудь может предложить эффективный способ сделать это, не полагаясь на встроенную панель администратора Django?
Я думал о том, чтобы использовать Group.get_or_create каждый раз, когда пользователь создается с помощью представления, и добавлять другое представление, добавляя и обновляя разрешения для определенной группы и используя групповые разрешения для обработки авторизации, но я не уверен, что это хорошая идея, если мне когда-нибудь понадобится внесите изменения в группу пользователей.
В Django есть PermissionRequiredMixin, который может быть получен для каждого представления. У permissionrequiredmixin есть свойство класса "permission_required". Таким образом, вы можете индивидуально определить требуемое разрешение для каждого представления. Также вы можете привязать пользователей к группам разрешений и назначить несколько разрешений для каждой группы.
https://docs.djangoproject.com/en/5.2/topics/auth/default/#the-permissionrequiredmixin-mixin
https://docs.djangoproject.com/en/5.2/topics/auth/default/#groups
Вот как вы можете определить пользовательские разрешения в проекте Django:
from django.contrib.auth.mixins import UserPassesTestMixin
from django.utils.decorators import method_decorator
class CustomPermissionMixin(UserPassesTestMixin):
required_role = None # Set this in your views
login_url = '/login/'
def test_func(self):
user = self.request.user
# Fail safely if role isn't configured
if self.required_role is None:
return False
return user.is_authenticated and user.role == self.required_role
и вот как использовать этот класс в ваших представлениях:
from django.views import View
from .permissions import CustomPermissionMixin
class MyView(CustomPermissionMixin, View):
required_role = "Admin" # Set role per view
def get(self, request):
return HttpResponse("Admin Panel")
Если вам нужна его функция, основанная на нем, я могу вам помочь :)