向Django管理添加权限

8 投票
1 回答
18260 浏览
提问于 2025-04-18 05:00

上个月我在StackOverflow和Django用户组的G+上,以及Django官网上发了个问题,但没有找到能解决我问题的答案。我想在Django的管理面板里添加一个新的权限,叫做view,这样用户就只能查看数据了!我还尝试过Django官网上的不同补丁,也试过django-databrowse,但都没有达到预期效果。最后我决定编辑auth/admin的视图。接下来我打算像这样添加查看权限:

1. 在默认权限列表中添加'view'

#./contrib/auth/management/init.py
def _get_all_permissions(opts):

    "Returns (codename, name) for all permissions in the given opts."
    perms = []
    for action in ('add', 'change', 'delete', 'view'):

        perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))

    return perms + list(opts.permissions)

2. 测试'view'权限是否已添加到所有模型中

run manage.py syncdb

这样之后,我就可以只给用户分配查看权限了。现在这个查看权限也必须能正常工作。所以我在django-adminview.py里写了这段代码:

for per in request.user.user_permissions_all():
    print per

这段代码会打印出登录用户被分配的权限,比如auth | permission | can view department等等。

现在我可以通过拆分这个句子来获取权限类型和模型名称。我会得到应用程序的所有模型名称,并匹配哪些数据应该可见。不过这并不是我真正需要的,但可以用。

所以我想问的是:

* 这样做是否正确,或者还有其他方法?我只想要一个能正常工作的解决方案。需要你的帮助 *

1 个回答

11

给默认权限列表添加'查看'权限

你的解决方案是可行的,但尽量不要直接修改源代码。其实有几种方法可以在框架内实现这个功能:

1. 在 post_syncdb() 时添加权限:

在你的应用的管理文件夹下创建一个文件:

from django.db.models.signals import post_syncdb
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Permission

def add_view_permissions(sender, **kwargs):
    """
    This syncdb hooks takes care of adding a view permission too all our 
    content types.
    """
    # for each of our content types
    for content_type in ContentType.objects.all():
        # build our permission slug
        codename = "view_%s" % content_type.model

        # if it doesn't exist..
        if not Permission.objects.filter(content_type=content_type, codename=codename):
            # add it
            Permission.objects.create(content_type=content_type,
                                      codename=codename,
                                      name="Can view %s" % content_type.name)
            print "Added view permission for %s" % content_type.name

# check for all our view permissions after a syncdb
post_syncdb.connect(add_view_permissions)

每当你执行'syncdb'命令时,系统会检查所有内容类型是否有'查看'权限,如果没有,就会创建一个。

2. 将权限添加到 Meta权限选项:

在每个模型下,你需要在它的Meta选项中添加类似这样的内容:

class Pizza(models.Model):
    cheesiness = models.IntegerField()

    class Meta:
        permissions = (
            ('view_pizza', 'Can view pizza'),
        )

这样做的效果和1是一样的,只不过你需要手动为每个类添加。

3. 在Django 1.7中新增,将权限添加到 Meta默认权限选项:

在Django 1.7中,他们增加了default_permissions这个Meta选项。在每个模型下,你需要将'查看'添加到default_permissions选项中:

class Pizza(models.Model):
    cheesiness = models.IntegerField()

    class Meta:
        default_permissions = ('add', 'change', 'delete', 'view')

测试'查看'权限是否添加到所有模型

至于测试用户是否拥有该权限,你可以使用has_perm()函数进行测试。例如:

user.has_perm('appname.view_pizza') # 如果用户'可以查看披萨',则返回True

撰写回答