Django - 如何为用户授予特定视图的权限?

25

从管理界面可以为用户或用户组分配权限,以允许其向模型中添加、更改或删除数据。

这很棒,但我还需要允许用户或用户组访问或不访问一组视图。我的网站上有某些类型的服务,因此我想允许某些用户访问特定的服务(页面/视图),但不允许他们访问其他服务。

那么,我如何允许某些用户/用户组访问特定的视图呢?谢谢!

5个回答

27

如果用户无法添加、更改某个模型等,则无法在管理界面中看到它。

如果我们谈论你自己创建的视图,那么你可以创建一个检查用户权限的功能,并且如果他们没有该权限,则返回404。权限与模型相关联,一个组可以被分配多个权限。

您可以像这样向模型添加权限:

# myproject/myapp/models.py

class MyModel(models.Model):
    class Meta:
        permissions = (
            ('permission_code', 'Friendly permission description'),
        )

然后,您可以像这样检查用户是否有权限:

@user_passes_test(lambda u: u.has_perm('myapp.permission_code'))
def some_view(request):
    # ...

通过使用权限,您可以轻松地通过管理员界面将它们添加到用户和组中,或从用户和组中删除它们。


是的,我指的是我创建的自定义视图,而不是管理员。 - avatar
谢谢。我会尝试一下。看起来相对容易。 - avatar
在这里使用@permission_required会更加简单和优雅。 - Manur
5
@Manur说的更好。我在2011年1月回答了这个问题:但我不记得那时候是否有“permission_required”装饰器。 - Marcus Whybrow
1
确保迁移或同步数据库以使用它们。我曾经绞尽脑汁地试图弄清楚这一点,直到我找到了这个链接:https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#custom-permissions - Jarie Bolander

10

你需要手动管理它,但这很容易。假设有一个属性来确定组是否有权限查看视图:然后你只需使用permission_required装饰器装饰该视图,如果问题很简单,只是判断用户是否具有特定的权限,或者使用user_passes_test如果问题比较复杂:

@user_passes_test(lambda u: u.is_allowed_to_see_view_myview())
def myview(request):
    ...etc...

假设is_allowed_to_see_view_myview是User对象上的某种方法。

身份验证文档相当全面。


4

对于基于类的视图,您可以将 UserPassesTestMixin 类继承到视图中,并定义 test_func

from django.contrib.auth.mixins import UserPassesTestMixin

class MainView(UserPassesTestMixin, View):

    def test_func(self):
        return self.request.user.has_perm('app.get_main_view')

请查看此文档以获取更多有关如何使用的细节:


重要信息,这是最近Django的功能(版本1.9+)。 - Drachenfels

2
如果您正在使用Django 1.9+,您应该能够使用PermissionRequiredMixin
例如:
from django.contrib.auth.mixins import PermissionRequiredMixin

class MainView(PermissionRequiredMixin, View):
    permission_required = 'my_services.foo_bar'
    ...

这基本上是UserPassesTestMixin的一个特殊情况,专门设计用于测试用户是否具有指定的权限。

1

权限系统是以模型为中心的,并假定权限与模型相关联。我认为以下两个选择是最佳选项:

A. 如果您的视图与某个特定模型相关,请像Marcus Whybrow建议的那样在该模型上使用自定义权限。

B. [未经测试,可能无法正常工作] 子类化User并在其中定义自己的权限。您不需要实际模型,它只是您应用程序的自定义权限包装器:

from django.contrib.auth.models import User
class MyUser(User):
    class Meta:
        permissions = (('can_visit_$viewset1', 'Can visit $view_set_1'))

不要忘记运行 syncdb 将自定义权限添加到数据库中。

截至Django 1.3,没有办法对User进行子类化(除了使用AUTH_PROFILE_MODULE,但这在这里并没有帮助)。 - SystemParadox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接