使用Django和django-guardian对象权限对每个对象进行分组

时间:2014-05-04 18:36:03

标签: django django-models django-guardian

我目前正在创建一个我拥有属于公司的员工的结构。 在这家公司内,我需要能够创建几个组。排名如果你愿意。您可以为较低级别分配较少的权限,为较高级别分配较多权限。

我想去寻找对象级权限,我注意到django-guardian项目给了我正确的需要。它适用于本机用户和组对象,因此我现在正在尝试找到一种在公司对象中实现本机组对象的方法。

我面临的问题是组中的名称是唯一的。因此,如果2家公司添加相同的组,则会发生错误。

我找到了一种在某种程度上有效的实现,但对我来说似乎非常'hacky'。在我的公司,我宣布了一个引用Group的组变量:

class Company(models.Model):
    ...
    groups = models.ManyToManyField(Group, through='CompanyRole')

CompanyRole基本上包含组名称以及对公司和组的引用

class CompanyRole(models.Model):
    group = models.ForeignKey(Group)
    company = models.ForeignKey(Company)
    real_name = models.CharField(max_length=60, verbose_name=_('Real name'))

    objects = CompanyGroupManager()

我使用方便的方法创建了一个自定义管理器来添加新的“公司组”

class CompanyGroupManager(models.Manager):
    def create_group(self, company, group_name):
        un_group_name = str(company.id) + '#' + group_name
        group = Group.objects.create(name=un_group_name)
        company_group = self.model(
            real_name=group_name, 
            company=company, 
            group=group
        )

        company_group.save(using=self._db)
        return company_group

这部分我并不真正感到难以理解。为了使用Group模型上的唯一名称更改问题,我使用了公司ID,哈希符号和实际组名称的组合来避免冲突。

现在我的问题是:在我的场景中是否有更好的方法,我错过了什么,或者这是完成我需要的好方法吗?

1 个答案:

答案 0 :(得分:2)

不幸的是,没有办法解决这个独特的要求,因为这个字段被用作id: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.Field.unique

您的选择如下:

1)模拟模型。

您基本上只需创建一个没有唯一要求的新Group模型。这里的缺点是你需要在任何地方使用它,所以如果这需要更新第三方应用程序,它可能是不值得的。

2)使你的名字独一无二。 (正如你所做的那样)

确保你很好地记录你的会议,以便所有未来的程序员都能知道他们在看什么。像“公司名称”#“组名”这样的东西可能比id更直观。如果a哈希可能出现在任一个中,那么使用更确定的分隔符(“__”是连接django中相关概念的一种相对常见的方式,我可能会这样做。)

我建议您添加以下内容,以便您轻松访问该名称。

def get_name(self):
    # Explain how you get the group name from your uniqueified name
    return self.name.split('#')[1] 

Group.add_to_class('get_name', get_name)

当您在应用中访问论坛名称时,请执行以下操作:

my_group.get_name()

您可能还希望将生成的唯一名称放入save()的重写版本中。这样可以让你在模型和视图之间进行更好的分割......