Мне нужно создать сайт для школы, где будет главный администратор, который может создавать других пользователей. Обычные администраторы (с правом `is_staff`) не должны иметь доступ к модели пользователя (`User`), но при этом они должны иметь доступ ко всем остальным моделям.
Однако, когда я захожу в админку под учетной записью обычного администратора, появляется ошибка "You don’t have permission to view or edit anything.", а когда я вхожу под главным администратором (с правами `is_staff` и `is_superuser`), все работает нормально. Мне нужно найти решение, чтобы обычный администратор имел доступ ко всем моделям, кроме модели `User`.
managers.py:
from django.contrib.auth.models import BaseUserManager
class CustomUserManager(BaseUserManager):
def _create_user(self, username, position, password, is_staff, is_superuser, **extra_fields):
if not username:
raise ValueError("Вы не ввели username!")
if not password:
raise ValueError("Вы не ввели пароль!")
user = self.model(
username=username,
position=position,
is_active=True,
is_staff=is_staff,
is_superuser=is_superuser,
**extra_fields
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, position="Администратор", password=None, **extra_fields):
return self._create_user(username, position, password, is_staff=False, is_superuser=False, **extra_fields)
def create_superuser(self, username, password=None, **extra_fields):
return self._create_user(
username,
position="Главный администратор",
password=password,
is_staff=True,
is_superuser=True,
**extra_fields
)
models.py:
from django.contrib.auth.models import (
AbstractBaseUser,
PermissionsMixin,
)
from django.db import models
from .managers import CustomUserManager
POSITION = [
('Главный администратор', 'Главный администратор'),
('Администратор', 'Администратор'),
]
class User(AbstractBaseUser, PermissionsMixin):
id = models.AutoField(primary_key=True, unique=True)
username = models.CharField(max_length=24, unique=True, verbose_name="Имя пользователя (на английском)")
position = models.CharField(choices=POSITION, default="Администратор", blank=False, null=False, max_length=21)
is_active = models.BooleanField(default=True, verbose_name="Активность")
is_staff = models.BooleanField(default=False, verbose_name="Администратор")
is_superuser = models.BooleanField(default=False, verbose_name="Главный администратор")
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
objects = CustomUserManager()
class Meta:
verbose_name = "Администратор"
verbose_name_plural = "Администраторы"
def __str__(self):
return self.username
def save(self, *args, **kwargs):
if self.position == "Главный администратор":
self.is_superuser = True
self.is_staff = True
elif self.position == "Администратор":
self.is_superuser = False
self.is_staff = True
super().save(*args, **kwargs)
forms.py:
from django import forms
from django.contrib.auth.forms import UserChangeForm
from .models import User
class CustomUserChangeForm(UserChangeForm):
password = forms.CharField(
widget=forms.PasswordInput(),
required=False,
help_text="Оставьте это поле пустым, если не хотите менять пароль."
)
class Meta:
model = User
fields = '__all__'
def save(self, commit=True):
user = super().save(commit=False)
password = self.cleaned_data.get('password')
if password:
user.set_password(password)
else:
user.password = User.objects.get(id=user.id).password
if commit:
user.save()
return user
admin.py:
from django.contrib import admin
from .models import User
from .forms import CustomUserChangeForm
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
form = CustomUserChangeForm
list_display = ('username', 'position')
ordering = ('username',)
fieldsets = (
(None, {'fields': ('username', 'password')}),
('Position', {'fields': ('position', )}),
)