Несколько разрешений для нескольких ролей в 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
`
затем я создам команду управления для создания указанных мною групп перед созданием проекта (просто чтобы не создавать группы вручную из панели администратора)
это хороший подход? есть какие-либо предложения? должен ли я также создать образец для подражания? для назначения разрешений?
то, что я пробовал, доказано выше