Поле пользователя Django is_staff установлено в true в экземпляре, но читается как false в классе разрешения

Я пытаюсь создать конечную точку api, которая выводит список всех пользователей в базе данных, но я хочу, чтобы это могли делать только сотрудники. По умолчанию при создании секретаря поле is_staff в модели пользователей устанавливается в значение True. В классе разрешений я проверяю, установлено ли это поле в true, и соответственно предоставляю разрешения.
Поскольку у меня много различных типов пользователей с немного отличающимися атрибутами, я создал конкретную базовую модель пользователя, которая наследуется другими моделями пользователей. Роль SECRETARY назначается сериализатором при обработке запроса конечной точки создания секретаря.



class User(AbstractBaseUser):

    class Roles(models.TextChoices):
        """define the user roles"""

        ADMIN = "ADMIN", "Admin"
        PRINTER = "PRINTER", "Printer"
        SECRETARY = "SECRETARY", "Secretary"
        PHOTOGRAPHER = "PHOTOGRAPHER", "Photographer"
        EDITOR = "EDITOR", "Editor"
        CLIENT = "CLIENT", "Client"
        SYSTEM = "SYSTEM", "System"
        APPLICANT = "APPLICANT", "Applicant"

    id = models.CharField(
        max_length=8, unique=True, primary_key=True, default=uidgen, editable=False
    )
    first_name = models.CharField("First Name", max_length=30, null=False)
    last_name = models.CharField("Last Name", max_length=30, null=True, blank=True)
    email = models.EmailField(
        verbose_name="Email", max_length=255, unique=True, null=False
    )
    username = None
    phone_number = models.CharField(
        "Phone Number", max_length=20, null=False, unique=True
    )
    dob = models.DateField(verbose_name="Date Of Birth", blank=True, null=True)
    role = models.CharField(max_length=50, default=Roles.CLIENT)
    date_joined = models.DateTimeField(verbose_name="Date Joined", auto_now_add=True)
    last_login = models.DateTimeField(verbose_name="Last Login", auto_now=True)
    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["phone_number"]
    is_staff = False
    is_superuser = False
    is_active = True
    is_contractor = False
    is_associate = False
    phone_is_verified = False
    email_is_verified = False

    objects = UserManager()

User manager:



class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError("The Email must be set")
        user = self.model(
            email=self.normalize_email(email),
        )
        if password:
            user.set_password(password)
        try:
            if user.role == User.Roles.SECRETARY:
                extra_fields.setdefault("is_staff", True)
            else:
                extra_fields.setdefault("is_staff", False)
        except AttributeError:
            user.role = User.Roles.ADMIN
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)
        extra_fields.setdefault("is_active", True)
        admin_user = self.create_user(email, password, **extra_fields)
        admin_user.role = User.Roles.ADMIN
        admin_user.save()
        return admin_user

Модель секретаря:


class Secretary(User):
    bank_number = models.CharField(max_length=50, null=True)
    is_staff = True

    class Meta:
        verbose_name = "Secretary"
        verbose_name_plural = "Secretaries"

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

    objects = UserManager()

Класс разрешения:


class UserListPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        print(request.user.is_staff)
        if view.action == "list" and request.user.is_staff:
            return True
        return False

    def has_object_permission(self, request, view):
        if view.action == "list" and request.user.is_staff:
            return True
        return False

Я создал секретаря вместе с маркером доступа и попытался получить доступ к конечной точке api только для сотрудников. Я получаю ответ:

{
    "detail": "You do not have permission to perform this action."
}

В выводе оболочки сервера оператор print выдает False. В оболочке django shell:

>>> sec = Secretary.objects.get(email='dinoseca@yahoo.de')
>>> sec.role
'SECRETARY'
>>> sec.is_staff
True

Когда я удаляю is_staff = True из модели секретаря, вышеприведенный фрагмент оболочки приводит к False

Мне кажется, что ошибка кроется где-то в моем UserManager или моей модели User.

Вам необходимо сохранить пользователя перед возвратом в методе create_user. self.model просто создает экземпляр, а метод save должен быть вызван для сохранения экземпляра в базе данных.

def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError("The Email must be set")
        user = self.model(
            email=self.normalize_email(email),
        )
        if password:
            user.set_password(password)
        try:
            user.is_staff = True if user.role == User.Roles.SECRETARY else False
        except AttributeError:
            user.role = User.Roles.ADMIN
        user.save(using=self._db)
        return user

Это также может помочь прояснить https://stackoverflow.com/a/51163172/11128969

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