AttributeError: 'Account' object has no attribute 'is_staff'

AttributeError: 'Account' object has no attribute 'is_staff'

我自定义了用户模型,这里是模型:

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


class AccountManager(BaseUserManager):

    def create_user(self, username=None, password=None, **kwargs):
        account = self.model(username=username)

        account.set_password(password)
        account.is_stuff = False
        account.save()

        return account

    def create_superuser(self, username, password, **kwargs):
        account = self.create_user(username, password, **kwargs)
        account.is_admin = True
        account.is_staff = True
        account.save()

        return account


class Account(AbstractBaseUser):
    username = models.CharField(max_length=40, unique=True)
    is_admin = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    initialized = models.BooleanField(default=False)

    USERNAME_FIELD = 'username'

    objects = AccountManager()

然后,当我尝试获取所有用户的列表时,它会抛出 AttributeError: 'Account' object has no attribute 'is_staff'

class GetUserList(ListAPIView):
    permission_classes = (permissions.IsAdminUser,)
    queryset = Account.objects.all()
    serializer_class = AccountSerializer

定义自己的权限后解决问题:

class IsAdminUser(permissions.BasePermission):

    def has_permission(self, request, view):
        return request.user.is_admin

然后

class GetUserList(ListAPIView):
    permission_classes = (IsAdminUser,)
    queryset = Account.objects.all()
    serializer_class = AccountSerializer

IsAdminUser calls is_staff 是在 django 的 auth 用户模型中定义的。所以如果你有自己的自定义用户模型,你还需要为此提供一个实现

在django的AbstractUserclass中,是一个BooleanField,可以看到here

正如@Sayse 和@Daniel 所指出的,您可以通过将 is_staff 字段添加到您的自定义用户模型来解决此问题:

is_staff = models.BooleanField(_('staff status'),default=False)

(对我有用)

对我来说,它通过在模型中添加这两个来工作

 is_staff = models.BooleanField(default=False)
 is_superuser = models.BooleanField(default=False)

然后在管理器中

def create_user(self, email, password=None):
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

def create_superuser(self, email, password):
        """
        Creates and saves a superuser with the given email and password.
        """
        user = self.create_user(
            email,
            password=password,
        )
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

这在 Django 3 中有效。
我已经在 Dev.to

上写了一些详细的 post

您不必使用 is_staff 或 is_admin,您可以只为您的模型创建一个 is_staff 属性。 示例:

    
class Account(AbstractBaseUser):
    username = models.CharField(max_length=40, unique=True)
    is_admin = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    initialized = models.BooleanField(default=False)

    USERNAME_FIELD = 'username'

    @property
    def is_staff(self):
        return self.is_admin

    objects = AccountManager()

这样您就可以毫无错误地使用您的自定义权限。