6

我正在开发一种产品,该产品允许不同的学校在线管理他们的内容。

其中一部分涉及设置我自己编写的基于角色的访问控制逻辑。本质上,每所学校都有自己的一组角色,这些角色拥有自己的一组权限。该软件的用户在任何给定时间都可能属于具有不同角色的多所学校。

由于各种原因,我想放弃这个,而是使用 Django 的组和权限以及像django-guardian这样的库。我面临的问题是我应该如何扩展 Groups 模型,以便我可以为每个新学校包含一个外键,并且仍然能够使用 Django 中的辅助方法以及 django-guardian 等库。

我想出的一种可能的方法是简单地根据事件名称创建组,例如“学校 1 - 管理员”、“学校 1 - 教师”、“学校 2 - 管理员”、“学校 2 - 教师”,并根据这个代替。我不应该这样做有充分的理由吗?

4

2 回答 2

5

经过仔细检查,django-guardian 能够解决我的需求。我在这里写了我的完整实现:​​http://pragmaticstartup.wordpress.com/2012/06/26/django-guardian-a-full-access-control-logic-acl-example/

于 2012-07-04T08:44:37.577 回答
0

为什么不混合两种方法呢?Django 模型允许继承。首先定义Role模型,包含允许的角色和学校模型。

然后,您可以从django.contrib.auth.GroupGroupRole 继承一个新模型。Django 将为您的模型创建一个新的数据库表,该表仅包含最初不在组中的属性,并带有外键到具有约束的适当组。更好的是,您将获得与原始组模型的自动反向关系,因此您可以编写如下内容:

class GroupRole(Group):
    role = models.ForeignKey(Role)
    school = models.ForeignKey(School)
    ...

g = Group.objects.get(id=1)
# you can access standard group items here g.<attribute> or g.grouprole.<attribute>
# you can access GroupRole attributes by doing g.grouprole.<some_attribute>

GroupRole.objects.filter(role__type='admin', school__location__state='NY')

有趣的是,这种关系是反射性的,所以如果不是太有用的话,这样的事情是有效的:

g.grouprole.grouprole.grouprole.grouprole.role

如果您获得一个没有与之关联的 grouprole 代理的基本组实例,那么您将抛出异常:

g = Group.objects.create(name='myplaingroup')
try:
    print g.grouprole
except GroupRole.DoesNotExist:
    print 'This is a normal group'

或者,您可以覆盖此行为以返回 None 而不是引发异常,甚至提供默认的 GroupRole。

于 2012-06-19T12:32:54.697 回答