mirolim-dev / Learn-DRF

I'm gonna upload several projects in this repo
Apache License 2.0
0 stars 0 forks source link

I stucked while adding new permissions to customUsers. I hope you can help me to solve it #2

Closed mirolim-dev closed 1 year ago

mirolim-dev commented 1 year ago

I stucked while adding new permissions to customUsers

I'm trying to add several permissions Some of them are saving without any problem. Any errors aren't raising when I give permissions, but I'm not being able to add these perms only. Nothing else

(
        ('can_view_socialmedia', "Can view socialmedia"),
        ('can_add_socialmedia', 'Can add socialmedia'),
        ('can_change_socialmedia', 'Can change socialmedia'),
)

to my adminstrator model but I stucked. After that I tried to add those conflict permissions by django signal. But nothing changed. I don't know why I can't add these permissions

Note! I already did makemigrations and migrate commands

Here you can see my code belong to giving permissions to users 👇👇👇

_variables.py file_

employees_permissions = {
    'boss': (
            ('can_view_boss', 'Can view boss'),
            ('can_add_boss', 'Can add boss'),
            ('can_change_boss', 'Can change boss'),
            ('can_delete_boss', 'Can delete boss'),

            ('can_view_teacher', "Can view teacher"),
            ('can_add_teacher', 'Can add teacher'),
            ('can_change_teacher', 'Can change teacher'),
            # ('can_delete_teacher', 'Can delete teacher'),

            ('can_view_adminstrator', "Can view adminstrator"),
            ('can_add_adminstrator', 'Can add adminstrator'),
            ('can_change_adminstrator', 'Can change adminstrator'),
            ('can_delete_adminstrator', 'Can delete adminstrator'),

            ('can_view_accountant', "Can view accountant"),
            ('can_add_accountant', 'Can add accountant'),
            ('can_change_accountant', 'Can change accountant'),
            ('can_delete_accountant', 'Can delete accountant'),

            ('can_view_services', 'Can view services'),
            ('can_view_subjects', 'Can view subjects'),
            ('can_view_groups', 'Can view groups'),
        ),

    'adminstrator': (
        ('can_view_teacher', "Can view teacher"),
        ('can_add_teacher', 'Can add teacher'),
        ('can_change_teacher', 'Can change teacher'),

        ('can_view_student', "Can view student"),
        ('can_add_student', 'Can add student'),
        ('can_change_student', 'Can change student'),

        ('can_view_studentpayment', "Can view studentpayment"),
        ('can_add_studentpayment', 'Can add studentpayment'),

        ('can_view_room', "Can view room"),
        ('can_add_room', 'Can add room'),
        ('can_change_room', 'Can change room'),

        ('can_view_subject', "Can view subject"),
        ('can_add_subject', 'Can add subject'),
        ('can_change_subject', 'Can change subject'),

        ('can_view_group', "Can view group"),
        ('can_add_group', 'Can add group'),
        ('can_change_group', 'Can change group'),

        ('can_view_socialmedia', "Can view socialmedia"),
        ('can_add_socialmedia', 'Can add socialmedia'),
        ('can_change_socialmedia', 'Can change socialmedia'),

        ('can_view_service', "Can view service"),
        ('can_add_service', 'Can add service'),
        ('can_change_service', 'Can change service'),

        ('can_view_serviceuser', "Can view serviceuser"),
        ('can_add_serviceuser', 'Can add serviceuser'),

        ('can_view_serviceusage', "Can view serviceusage"),
        ('can_add_serviceusage', 'Can add serviceusage'),
        ('can_change_serviceusage', 'Can change serviceusage'),

        ('can_view_schedule', "Can view schedule"),
        ('can_add_schedule', 'Can add schedule'),
        ('can_change_schedule', 'Can change schedule'),
        ('can_delete_schedule', 'Can delete schedule'),

        ('can_view_servicepayment', "Can view servicepayment"),
        ('can_add_servicepayment', 'Can add servicepayment'),

        ('can_view_interestor', "Can view interestor"),          
    ),

    'teacher': (),
    'accountant': (),
}

_my employees' models_

from django.db import models

from main.models import CustomUser, Subject
from .variables import employees_permissions
# from study.models import Schedule
# Create your models here.

class Boss(models.Model):

    class Meta:
        verbose_name_plural = "Bosses"
        ordering = ['-created_at']    
        permissions = employees_permissions['boss']

    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    is_active = models.BooleanField(default=True)
    salary = models.DecimalField(max_digits=15, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.user}"

    def calculate_kpi(self):
        pass

class Adminstrator(models.Model):
    class Meta:
        verbose_name_plural = 'Admintrators'
        ordering = ['-created_at']
        permissions = employees_permissions['adminstrator']

    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    is_active = models.BooleanField(default=True)
    salary = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self) -> str:
        return f"{self.user}"

    def calculate_kpi(self):
        pass

class Accountant(models.Model):
    class Meta:
        verbose_name_plural = 'Accountants'
        ordering = ['-created_at']
        permissions = employees_permissions['accountant']
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    is_active = models.BooleanField(default=True)
    salary = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self) -> str:
        return f"{self.user}"

    def calculate_kpi(self):
        pass

class Teacher(models.Model):
    class Meta:
        verbose_name_plural = 'Teachers'
        ordering = ['-created_at']
        permissions = employees_permissions['teacher']

    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    is_active = models.BooleanField(default=True)
    salary = models.DecimalField(max_digits=10, decimal_places=2)
    subjects = models.ManyToManyField(Subject)
    created_at = models.DateTimeField(auto_now_add=True, editable=False)

    def __str__(self) -> str:
        return f"{self.user}"

    def calculate_kpi(self):
        pass

    def get_all_schedules(self):
        schedules = []
        for group in self.get_all_groups():
            schedules.extend(group.schedule_set.all().select_related('group', 'room'))
        return schedules

    def get_all_groups(self):
        return self.group_set.select_related('teacher').all()
        # pass

# signals here
from django.dispatch import receiver
from django.db.models.signals import post_save
from django.contrib.auth.models import Permission

@receiver(post_save, sender=Boss)
@receiver(post_save, sender=Teacher)
@receiver(post_save, sender=Adminstrator)
def change_user_staff_status(sender, instance, created, **kwargs):
    """Grant access to Django's admin dashboard for new employees."""
    if created and hasattr(instance, 'user'):
        user = instance.user
        user.is_staff = True
        model_name = instance.__class__.__name__.lower()
        permissions = employees_permissions.get(model_name)
        permission_ids = []
        for codename, name in permissions:
            permission = Permission.objects.filter(name__icontains=name).exclude(content_type__app_label='auth')
            if len(permission) > 1:
                for pr in permission:
                    permission_ids.append(pr.id)
            elif len(permission) == 1:
                permission_ids.append(permission[0].id)
        print("Perm IDs: ", permission_ids)
        auth_permission_ids = Permission.objects.filter(content_type__app_label='auth').values_list('id', flat=True)
        user.user_permissions.add(*permission_ids)
        user.save()
        user_perms_ids = user.user_permissions.all().values_list('id', flat=True) #user permission after saving
        conflict_ids = list(set(permission_ids) - set(user_perms_ids))
        print(f"Conflict ids: {conflict_ids}")
        user.user_permissions.remove(*auth_permission_ids)
        if permission_ids != []:
            user.user_permissions.add(*conflict_ids)
            user.save()
        final_user_perms_ids = [perm_id for perm_id in user.user_permissions.all().values_list('id', flat=True)]

        print(f"Difference beetween: before/after conflict\n{list(set(final_user_perms_ids) - set(user_perms_ids))}")

_my last migration file _

# Generated by Django 4.2 on 2023-06-25 22:28

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ('employee', '0004_alter_accountant_user_alter_adminstrator_user_and_more'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='accountant',
            options={'ordering': ['-created_at'], 'permissions': (), 'verbose_name_plural': 'Accountants'},
        ),
        migrations.AlterModelOptions(
            name='adminstrator',
            options={'ordering': ['-created_at'], 
                     'permissions': (('can_view_teacher', 'Can view teacher'), ('can_add_teacher', 'Can add teacher'), 
                                     ('can_change_teacher', 'Can change teacher'), ('can_view_student', 'Can view student'), 
                                     ('can_add_student', 'Can add student'), ('can_change_student', 'Can change student'), 
                                     ('can_view_studentpayment', 'Can view studentpayment'), 
                                     ('can_add_studentpayment', 'Can add studentpayment'), ('can_view_room', 'Can view room'), 
                                     ('can_add_room', 'Can add room'), ('can_change_room', 'Can change room'), 
                                     ('can_view_subject', 'Can view subject'), ('can_add_subject', 'Can add subject'), 
                                     ('can_change_subject', 'Can change subject'), ('can_view_group', 'Can view group'), 
                                     ('can_add_group', 'Can add group'), ('can_change_group', 'Can change group'), 
                                     ('can_view_socialmedia', 'Can view socialmedia'), ('can_add_socialmedia', 'Can add socialmedia'), 
                                     ('can_change_socialmedia', 'Can change socialmedia'), ('can_view_service', 'Can view service'), 
                                     ('can_add_service', 'Can add service'), ('can_change_service', 'Can change service'), 
                                     ('can_view_serviceuser', 'Can view serviceuser'), ('can_add_serviceuser', 'Can add serviceuser'), 
                                     ('can_view_serviceusage', 'Can view serviceusage'), ('can_add_serviceusage', 'Can add serviceusage'), 
                                     ('can_change_serviceusage', 'Can change serviceusage'), ('can_view_schedule', 'Can view schedule'), 
                                     ('can_add_schedule', 'Can add schedule'), ('can_change_schedule', 'Can change schedule'), 
                                     ('can_delete_schedule', 'Can delete schedule'), ('can_view_servicepayment', 'Can view servicepayment'), 
                                     ('can_add_servicepayment', 'Can add servicepayment'), ('can_view_interestor', 'Can view interestor')), 'verbose_name_plural': 'Admintrators'},
        ),
        migrations.AlterModelOptions(
            name='boss',
            options={'ordering': ['-created_at'], 'permissions': (('can_view_boss', 'Can view boss'), ('can_add_boss', 'Can add boss'), ('can_change_boss', 'Can change boss'), ('can_delete_boss', 'Can delete boss'), ('can_view_teacher', 'Can view teacher'), ('can_add_teacher', 'Can add teacher'), ('can_change_teacher', 'Can change teacher'), ('can_view_adminstrator', 'Can view adminstrator'), ('can_add_adminstrator', 'Can add adminstrator'), ('can_change_adminstrator', 'Can change adminstrator'), ('can_delete_adminstrator', 'Can delete adminstrator'), ('can_view_accountant', 'Can view accountant'), ('can_add_accountant', 'Can add accountant'), ('can_change_accountant', 'Can change accountant'), ('can_delete_accountant', 'Can delete accountant'), ('can_view_services', 'Can view services'), ('can_view_subjects', 'Can view subjects'), ('can_view_groups', 'Can view groups')), 'verbose_name_plural': 'Bosses'},
        ),
        migrations.AlterModelOptions(
            name='teacher',
            options={'ordering': ['-created_at'], 'permissions': (), 'verbose_name_plural': 'Teachers'},
        ),
    ]

My custom user model

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

class CustomUserManager(BaseUserManager):
    def create(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('The Email field must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True')

        return self.create(email, password, **extra_fields)

class CustomUser(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255, blank=True)
    last_name = models.CharField(max_length=255, blank=True)
    email = models.EmailField(unique=True)
    password = models.CharField(max_length=128)
    phone = models.CharField(max_length=20)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True, null=True)
    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    def get_full_name(self):
        return f"{self.first_name} {self.last_name}"

    def get_short_name(self):
        return self.first_name

    # def has_perm(self, perm, obj=None):
    #     return True

    # def has_module_perms(self, app_label):
    #     return True

    def has_perm(self, perm, obj=None):
        return super().has_perm(perm, obj)

    def has_module_perms(self, app_label):
        return super().has_module_perms(app_label)

    def get_user_type(self):
        # add your implementation here
        return []

    def __str__(self):
        return self.email