django-guardian 如何使对象继承相关对象的权限?
我有两个模型:
class ContactGroup(models.Model):
name = models.CharField(max_length=40)
class Meta:
permissions=(('view_group_contacts', 'View contacts from group'))
class Contact(models.Model):
name = models.CharField(max_length=40)
group = models.ForeignKey(ContactGroup)
class Meta:
permissions=(('view_contact', 'View contact'))
我该怎么做才能让django guardian在我执行`get_objects_for_user(User, 'appname.view_contact')`时考虑ContactGroup的权限?同时又能保留对单个Contact更改权限的选项?(不是排除,而是当用户没有整个组的权限时,仍然可以给他们查看单个联系人的权限)
2 个回答
2
这个方法看起来很糟糕,它没有考虑到每个对象的变化(如果remove=False,它会把所有的权限重置为ContactGroup
的权限)。不过,如果需要的话,可以重新写一下,保留这些变化。我打算把它和“与组同步权限”这个按钮连接起来,这样只有在用户请求的时候才会执行。它的主要优点是可以按照预期与get_objects_for_user
一起工作。
def syncPerms(source, remove=False):
if not isinstance(source, ContactGroup):
return False
contacts= source.client_set.all()
user_perms=get_users_with_perms(source, attach_perms=True)
for contact in contacts:
for user, perm in user_perms.iteritems():
if u'view_group_contacts' in perm:
assign_perm('view_contact', user,client)
else:
if remove:
remove_perm('view_contact', user, client)
2
抱歉,django-guardian 不支持这种行为。至于 has_perm
,如果用在查询集上会非常低效,因为我们需要对表中的每一行都执行至少一次查询。
不过,你可以先对 ContactGroup
使用 get_objects_for_user
,然后再对 Contact
使用这个方法,并把第二个查询的结果和第一个查询的结果合并起来。大致可以这样做:
contact_groups = get_objects_for_user(user, 'appname.view_group_contacts', ContactGroup)
contacts = get_objects_for_user(user, 'appname.view_contact', Contact)
不过合并这些结果还是有点问题,但总的来说,这是可行的。