超级用户无法访问Django管理面板,显示“您没有权限查看或编辑任何内容”,

p8h8hvxi  于 2023-01-06  发布在  Go
关注(0)|答案(4)|浏览(320)

我在Django中创建了一个自定义用户模型== 3.2.3
下面是我的model. py文件

class MyUserManager(BaseUserManager):
""" A custom Manager to deal with emails as unique identifer """
def _create_user(self, email, password, **extra_fields):
    """ Creates and saves a user with a given email and password"""

    if not email:
        raise ValueError("The Email must be set!")

    email = self.normalize_email(email)
    user = self.model(email=email, **extra_fields)
    user.set_password(password)
    user.save(using=self._db)
    return user

def create_superuser(self, email, password, **extra_fields):
    extra_fields.setdefault('is_staff', True)
    extra_fields.setdefault('is_superuser', True)
    extra_fields.setdefault('is_active', True)

    if extra_fields.get('is_staff') is not True:
        raise ValueError('Superuser must have is_staff=True')
    if extra_fields.get('is_superuser') is not True:
        raise ValueError('Superuser must have is_superuser=True')
    return self._create_user(email, password, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):

email = models.EmailField(max_length=60, unique=True, verbose_name='Email')
first_name = models.CharField(max_length=30, verbose_name='First Name')
last_name = models.CharField(max_length=30, verbose_name='Last Name')
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ('first_name', 'last_name')

objects = MyUserManager()

def __str__(self):
    return self.email

def get_short_name(self):
    return self.first_name

def has_perm(self, perm, obj=None):
    return self.is_admin

def has_module_perms(self, app_label):
    return self.is_admin

class Meta:
    verbose_name_plural = "Users"

Here is my admin.py file

class MyUserAdmin(UserAdmin):
form = UserchangeForm
add_form = UserCreationForm

list_display = ('email', 'first_name', 'last_name', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
    (None, {'fields': ('email', 'password')}),
    ('Personal info', {'fields': (('first_name', 'last_name'))}),
    ('Permissions', {'fields': ('is_admin',)}),
)

add_fieldsets = (
    (None, {
        'classes': ('Wide',),
        'fields': ('email', 'first_name', 'last_name')
    }),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()

admin.site.register(User, MyUserAdmin)

迁移并创建超级用户后,当我登录管理面板时,显示**"You don't have permission to view or edit anything"(您没有查看或编辑任何内容的权限)。**
我在StackOverflow和其他网站上看到了很多解决方案,他们都建议添加我已经添加的has_module_permshas_perm

n3h0vuf2

n3h0vuf21#

内置的用户模型有两个字段指示用户的admin / staff状态,即is_superuseris_staff,超级用户具有执行任何操作的权限。这里的问题是您创建了一个 extra 字段is_admin,并且还覆盖了has_perm。等等(这是一种糟心的方式),因此只有将此字段设置为True的用户才拥有所有权限(其他用户即使被授予权限,也不会拥有它,因为您已经以这种方式覆盖了它)。
您需要将is_admin重命名为is_superuser,并 * 删除 * 您的has_permhas_module_perms

class User(AbstractBaseUser, PermissionsMixin):
    ...
    # ... is a placeholder for your code, strikethroughs mean you should remove the line
    is_admin = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    ...
    
    def has_perm(self, perm, obj=None):
        return self.is_admin
    
    def has_module_perms(self, app_label):
        return self.is_admin
    ...

同样,在MyUserAdmin中,您提到了is_admin,请将其重命名为is_superuser

0pizxfdo

0pizxfdo2#

遇到了同样的问题。然后我把'password=password'和'username=username'一起传入函数中,就像你在下面看到的粗体一样,它解决了这个问题:

class MyAccountManager(BaseUserManager):
    def create_user(self, email, username, password):
        if not email:
            raise ValueError('Please add an email address')
        if not username:
            raise ValueError('Please add an username')

        **user = self.model(email=self.normalize_email(
            email), username=username, password=password)**

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

    def create_superuser(self, email, username, password):
    #I have the below in my create_superuser function, I don't see it in your code:
        **user = self.create_user(email=self.normalize_email(
            email), username=username, password=password)**

此外,请确保将AUTH_USER_MODEL = 'accounts.User'添加到settings.py

9fkzdhlc

9fkzdhlc3#

所以这是一个奇怪的问题,但我希望这能帮助一些人。上面是覆盖Django用户模型的一个相当正常的方法,子类化AbstractBaseUserAbstractUser
但是,要做到这一点,您需要创建自己的Admin类,这些类通常要么直接指向UserCreationFormUserChangeForm(它们位于django.contrib.auth.forms模块中),要么指向一个定制表单,该表单将它们中的任何一个子类化。
默认情况下,UserCreationForm不包含is_superuser值,这意味着使用此表单在admin中创建帐户时,会将此值保留为false -这意味着您可以创建一个可以登录的帐户,但它还没有查看任何内容的显式或隐式权限。
如果您内省from django.contrib.auth.forms.UserCreationForm中的实际Form类,这就是预期的行为,来自文档字符串:

"""
A form that creates a user, with no privileges, from the given username and password.
"""

对我来说,我可以用两种方法来解决这个问题:

**1 -**您可以确保is_superuser被手动添加到您的初始UserCreationForm中,方法是确保它被显式地列在您的Admin类的add_fieldsets元组中,我的元组在这里:

add_fieldsets = (
    (
        None,
        {
            "classes": ("wide",),
            "fields": (
                "email",
                "password1",
                "password2",
                "is_staff",
                "is_active",
                "is_superuser"
            ),
        },
    ),
)

**2 -**您可以通过确保它在Admin类fieldsets元组中显式列出来确保它是手动添加到UserChangeForm的,这与上面的内容相同,但在ChangeForm中调用,而不是在CreationForm中调用。

qacovj5a

qacovj5a4#

在我的例子中,我的自定义用户模型的***has_perm()***返回None值。

Before: 
    def has_perm(self, perm, obj=None):
        return self.is_admin

After:         
    def has_perm(self, perm, obj=None):
        return True

上面的答案可能会有所帮助,为什么self.is_admin返回None。

相关问题