Reputation: 152
I have a custom user model, and I'm able to create groups without giving necessary permissions. I created a group by giving permission to view and change users. I added a staff user to that group without escalating them as an admin user or a superuser. But that user can edit admin user. How I can prevent users in that specific group from editing the admin user?
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
raise ValueError("Users must have an username")
user = self.model(
email=self.normalize_email(email),
username=username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=self.normalize_email(email),
username=username,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class User(AbstractBaseUser,PermissionsMixin):
email = models.EmailField(verbose_name='email', max_length=80, unique=True)
username = models.CharField(max_length=30, unique=True)
first_name = models.CharField(max_length=100,null=True)
last_name = models.CharField(max_length=100,null=True)
phone_no = models.CharField(max_length=12, null=True)
date_joined = models.DateField(
verbose_name='date joined', auto_now_add=True)
last_login = models.DateField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
address = models.CharField(max_length=500, null=True, blank=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
objects = MyAccountManager()
def __str__(self):
return self.email
# def has_perm(self, perm, obj=None):
# return self.is_admin
def has_module_perms(self, app_label):
return True
Upvotes: 0
Views: 765
Reputation: 153
For this, you need to separate the models virtually. You can use Django's Proxy Model. Add the following code to the bottom of your models.py.
from django.contrib.auth.models import UserManager
class StaffManager(UserManager):
def get_queryset(self):
qs = super().get_queryset()
return qs.filter(is_staff=True)
class StaffProxyModel(User):
objects = StaffManager()
class Meta:
proxy = True
verbose_name = 'Staff'
verbose_name_plural = 'Staffs'
#admin.py
from django.contrib.auth.admin import UserAdmin
class StaffProxyModelAdmin(UserAdmin):
pass
admin.site.register(StaffProxyModel, StaffProxyModelAdmin)
After making the changes run python manage.py makemigrations
and python manage.py migrate
. After doing above steps you'll be able to see "Staff proxy model" in the list of permissions. Grant change and view access to this model to your group. Your problem should be solved.
Django will see the proxy model as a separate model although, at the database level, both User and Staff models are stored in the same table.
Upvotes: 1