如何使用Django的组和权限?

87 投票
1 回答
46276 浏览
提问于 2025-04-16 10:30

我明白一些基本的用户操作,比如身份验证、登录、创建账户等等。但现在我想开始研究群组和权限。

请问关于Django的群组和权限的文档在哪里?这个链接不是我需要的: http://docs.djangoproject.com/en/dev/topics/auth/

1 个回答

123

首先,你需要问自己几个问题:你需要什么样的权限?具体是怎样的权限?这里的“怎样”是指你想要的是针对整个模型的权限,还是针对单个对象的权限。举个例子,如果你有一个叫“汽车”的模型,如果你想给所有汽车设置权限,那就用模型级权限;但如果你想给每辆车单独设置权限,那就用对象级权限。你可能需要两种权限,这没问题,后面会解释。

对于模型权限,Django大部分情况下会帮你处理。每个模型,Django会自动创建一些权限,格式是'appname.permissionname_modelname'。比如,如果你有一个叫“drivers”的应用,里面有一个汽车模型,那么就会有一个权限是'drivers.delete_car'。Django自动创建的权限通常包括创建、修改和删除。奇怪的是,他们没有包括读取权限,你需要自己添加。还有,Django把CRUD中的“更新”改成了“修改”,不知道为什么。要给模型添加更多权限,比如读取权限,你可以使用Meta类:

class Car( models.Model ):
    # model stuff here
    class Meta:
        permissions = ( 
            ( "read_car", "Can read Car" ),
        )

注意,permissions是一个元组的集合,元组里的内容是上面提到的权限和对该权限的描述。虽然你不一定要遵循permname_modelname的命名规则,但我通常会坚持这个规则。

最后,要检查权限,你可以使用has_perm:

obj.has_perm( 'drivers.read_car' )

这里的obj可以是用户或组的实例。我觉得写一个函数来做这个会更简单:

def has_model_permissions( entity, model, perms, app ):
    for p in perms:
        if not entity.has_perm( "%s.%s_%s" % ( app, p, model.__name__ ) ):
            return False
    return True

这里的entity是要检查权限的对象(可以是组或用户),model是模型的实例,perms是要检查的权限列表(比如['read', 'change']),app是应用的名称。要进行和上面has_perm相同的检查,你可以这样调用:

result = has_model_permissions( myuser, mycar, ['read'], 'drivers' )

如果你需要使用对象权限或行权限(它们是同一个意思),那么Django本身就不能完全满足你的需求。好在你可以同时使用模型权限和对象权限。如果你想要对象权限,你需要自己编写代码(如果使用的是1.2及以上版本),或者找一个别人写的项目。我个人喜欢的一个是django-objectpermissions,来自washingtontimes。

撰写回答