Несколько разрешений для нескольких ролей в django

в настоящее время я работаю над новостным проектом, в котором у меня есть автор новостей, статей и т.д.

я использую прокси-модели, я создал базовую пользовательскую модель и создал еще несколько пользовательских моделей от имени NewsWritetUser, и она унаследовала мета-класс в прокси-модели от моей базовой пользовательской модели .

у меня проблема, пользователь может быть news_writer , автором статьи и т.д. Вместе взятыми, я хочу создать систему разрешений для ее решения,

это мой models.py :

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin

from home.urls import app_name


class User(AbstractBaseUser , PermissionsMixin):
    USER_TYPE_CHOICES = [
        ('chief_editor', 'Chief Editor'),
        ('news_writer', 'News Writer'),
        ('article_writer', 'Article Writer'),
        ('hadith_writer', 'Hadith Writer'),
        ('contactus_admin', 'Contact Us User'),
        ('none' , 'No Specified Duty')
    ]


    email = models.EmailField(max_length=225 , unique=True)
    phone_number = models.CharField(max_length=11 , unique=True)
    full_name = models.CharField(max_length=100)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default = True)
    is_superuser = models.BooleanField(default = False)
    national_id = models.CharField(max_length=15 , unique=True)
    date_joint = models.DateTimeField(auto_now_add=True)
    duty_type = models.CharField(max_length=30 , choices=USER_TYPE_CHOICES , default='none')

    USERNAME_FIELD = 'national_id'
    REQUIRED_FIELDS = ['email' , 'phon_number' , 'full_name' , 'national_id']


    def __str__(self):
        return f' ID : {self.national_id} - Name : {self.full_name} - Phone : {self.phone_number} - Rule : {self.duty_type}'


    def has_prerm(self , perm , obj = None):
        if self.is_superuser:
            return True
        if self.duty_type == 'chief-editor':
            return (
                perm.startswith('news.') or perm.startswith('article.') or perm.startswith('hadith.') or perm.startswith('contactus.')
            )
        elif self.duty_type == 'news_writer':
            return perm.startswith('news.')
        elif self.duty_type == 'article-writer':
            return perm.startswith('articles.')
        elif self.duty_type == ('hadith_writer'):
            return perm.startswith('hadith.')
        elif self.duty_type == 'contactus_admin':
            return perm.startswith('contactus.')

    def has_module_perm(self , app_label):
        if self.is_superuser:
            return True
        elif self.duty_type == 'chief_editor':
            return app_label in ['news' , 'articles' , 'hadiths' , 'contacus']
        elif self.duty_type == 'news_writer':
            return app_label =='news'
        elif self.duty_type == 'article_writer':
            return app_label == 'articles'
        elif self.duty_type == 'hadith_writer':
            return app_label == 'hadiths'
        elif self.duty_type == 'contactus_admin':
            return app_label == 'contactus'`

но есть проблема, у пользователя может быть только разрешение ( правило). я хочу сделать так, чтобы у пользователя могло быть несколько ролей и разрешений, поэтому я должен использовать группы! . я должен назначить группы для пользователя .

я подумывал о создании поля "многие ко многим", например : `

from django.contrib.auth.modeels import .... Group`
   .
   .
   .
   groups = models.ManyToManyField(Group, blank=True)
   .
   .
   def has_perm(self, perm, obj=None):
        if self.is_superuser:
            return True
        
        group_names = self.groups.values_list('name', flat=True)
        if 'chief_editor' in group_names:
            return True  # full access for chief_editor
        
        if 'news_writer' in group_names and perm.startswith('news.'):
            return True
        
        if 'article_writer' in group_names and perm.startswith('articles.'):
            return True
        
        if 'hadith_writer' in group_names and perm.startswith('hadith.'):
            return True
        
        if 'contact_us_user' in group_names and perm.startswith('contactus.'):
            return True
        
        return False

         ... other methods like has_module_perm
`

затем я создам команду управления для создания указанных мною групп перед созданием проекта (просто чтобы не создавать группы вручную из панели администратора)

это хороший подход? есть какие-либо предложения? должен ли я также создать образец для подражания? для назначения разрешений?

то, что я пробовал, доказано выше

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