Управление группами 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")


Если вам нужна его функция, основанная на нем, я могу вам помочь :)

Вернуться на верх