Django - 具有自定义用户模型的PermissionRequiredMixin以及AUTHENTICATION_BACKENDS

时间:2016-01-24 05:54:35

标签: django permissions django-allauth manytomanyfield django-custom-user

我正在使用Django 1.9。当我尝试将PermissionRequiredMixin添加到基于类的视图时,似乎没有按预期工作。我在auth_group中创建了一个新用户。此auth_group对任何应用或模型都没有任何权限。此新用户不是超级用户或管理员用户。但该应用程序并不阻止此用户访问需要permission_required的特定视图。

首先,我试图确保用户没有权限:

user.get_all_permissions() # return set() - empty permission, which is correct.
user.is_superuser # return false, which is correct.
user.has_perm('myapp.add_something or even any words that make no sense')  # always return true, which is very weird.

该应用具有自定义用户模型,并且还使用django-allauth作为AUTHENTICATION_BACKENDS。我不确定PermissionRequiredMixin是否会检查user.has_perm()并且它总是返回true,这就是为什么检查权限没有按预期工作的原因?

# views.py
class My_View(PermissionRequiredMixin, View):
    permission_required = 'polls.can_vote'

    def get(self, request, *args, **kwargs):
        # do something...
        return render(request, "template.html", {})


# models.py - Custom User Model
class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    group = models.ManyToManyField(Group, through='UserGroupRelationship')
    .... 

# models.py - many-to-many relationship between user and group
class UserGroupRelationship(models.Model):
    user = models.ForeignKey("CustomUser") 
    user_group = models.ForeignKey(Group)

我还尝试了旧方法来检查urls.py中的权限。它也不会阻止用户访问,因此我认为这不是使用PermissionRequiredMixin的问题。

urlpatterns = patterns('',

    (r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),
)

1 个答案:

答案 0 :(得分:2)

在这个问题上花了几天之后,我终于找到了原因。

当我查看有关PermissionRequiredMixin的源代码时,我发现PermissionRequiredMixin确实检查了user.has_perm()。当我试图找到has_perm()的源代码时,我发现我的代码(从Django's document的自定义用户模型示例复制而来)包含以下重写方法......

def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

这就是为什么user.has_perm('任何')总是返回true的原因,这也会影响PermissionRequiredMixin的功能。因此,如果您是Django的新手,并尝试从文档中复制一些示例代码,则需要非常小心每一行...