【问题标题】:AttributeError: 'Account' object has no attribute 'is_staff'AttributeError:“帐户”对象没有属性“is_staff”
【发布时间】:2016-04-13 11:30:02
【问题描述】:

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

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

【问题讨论】:

  • 您尚未在模型上定义is_staff 字段。你打算这样做吗?
  • is_staff 字段对于我的自定义 AbstractUser 不是必需的,因为在这种情况下我根本没有使用 @DanielRoseman 有什么选择!
  • 在你的create_user 中有一行self.is_stuff=False 我认为应该是self.is_staff=False

标签: django django-authentication


【解决方案1】:

IsAdminUser 调用is_staff,这是在 django 的 auth 用户模型上定义的。因此,如果您有自己的自定义用户模型,您还需要为此提供一个实现

在django的AbstractUser类中,它是一个BooleanField,你可以看到here

【讨论】:

    【解决方案2】:

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

     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 上写了一篇详细的帖子

    【讨论】:

      【解决方案3】:

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

      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,您可能只想创建return request.user.is_admin,因为如果用户不是管理员,则不会返回任何内容,这可能会导致意外结果。
      【解决方案4】:

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

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

      (这对我有用)

      【讨论】:

        【解决方案5】:

        你不必使用 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()
        
        

        这样您就可以使用您的自定义权限而不会出现任何错误。

        【讨论】:

          猜你喜欢
          • 2021-06-29
          • 1970-01-01
          • 2022-07-16
          • 2021-08-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-01
          • 2021-04-19
          相关资源
          最近更新 更多