Multiple permissions for multiple roles in django

im currently working on a news project which i have news-writer , article-writer etc .

im using proxy models , i created a base User model and i created more user models in the name of NewsWritetUser and it has inherited in Meta class in proxy model from my base User model .

i have a problem , a user , can be news_writer , article writer and etc together , i want to create a permission system to handle it ,

this is my 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'`

but it has a problem , a user can only has a permission ( rule ) . i want to do smt that a user can have few roles and permissions , so i should use groups ! . i should set groups to a user .

i was thinking about creating a many to many field like : `

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
`

then i will create a management command to create my specified groups before building the project ( just to not manually creating groups from admin panel )

is it a good approach ? any suggestion ? should i create a role model too ? for assigning permissions ?

what i tried is proven above

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