我正在开发一种产品,允许不同的学校在线管理他们的内容。
部分内容涉及设置我自己编写的基于角色的访问控制逻辑。从本质上讲,每所学校都有自己的一组角色,这些角色拥有自己的一组权限。该软件的用户可以属于在任何给定时间具有不同角色的多所学校。
出于各种原因,我想放弃这个,而是使用Django的组和权限以及像django-guardian这样的库。我面临的问题是我应该如何扩展Groups模型,以便我可以在每个新学校中包含一个外键,并且仍然能够使用Django中的辅助方法以及像django-guardian这样的库。
我提出的一种可能的方法是简单地根据事件名称创建组,例如“学校1 - 管理员”,“学校1 - 教师”,“学校2 - 管理员”,“学校2 - 教师”和查询基于此的权限。有这么好的理由我不应该这样做吗?
答案 0 :(得分:5)
经过仔细检查,django-guardian能够解决我的需求。我在这里写了关于我的完整实现的文章:http://pragmaticstartup.wordpress.com/2012/06/26/django-guardian-a-full-access-control-logic-acl-example/
答案 1 :(得分:0)
为什么不将两种方法混合使用? Django模型允许inheritence。首先定义Role
模型,允许角色和学校模型。
然后您可以从django.contrib.auth.Group
继承GroupRole继承新模型。 Django将为您的模型创建一个新的db表,其中仅包含最初不在组中的属性,并且带有带有约束的相应组的外键。更好的是,您将获得与原始组模型的自动反向关系,因此您可以编写如下内容:
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。