【问题标题】:How to dynamically name permissions in a Django abstract model class?如何在 Django 抽象模型类中动态命名权限?
【发布时间】:2011-02-10 22:22:42
【问题描述】:

我想在抽象模型类上定义一些自定义权限,然后由所有子类继承,而不是给权限一个可以应用于任何子类模型类型的通用对象名称,我想基本上使用子模型的 verbose_name_plural 属性作为权限名称和描述的一部分(例如 ('view_classname', 'Can view classname')),模拟 Django 的默认行为。

所以,我希望做的是这样的事情(这是行不通的,因为verbose_name_plural 未在此上下文中定义):

class AbstractModel(models.Model):
    class Meta:
        abstract = True
        permissions = (
            (u'view_%ss' % verbose_name_plural, u'Can view %s' % verbose_name_plural),
        )

(这个问题在http://code.djangoproject.com/ticket/10686也有描述,其中包括一个补丁,实现了权限定义中%(class)s的动态替换,但是这个补丁从来没有被接受,我的生产环境也不允许打补丁。)

【问题讨论】:

标签: django django-models django-permissions


【解决方案1】:

你能用类装饰器而不是抽象模型类来完成这个吗?

def with_view_perm(cls):
    vn = cls.Meta.verbose_name_plural
    perms = (('view_%s' % vn, 'Can view %s' % vn),)
    cls.Meta.perms += perms
    return cls

@with_view_perm
class Child(models.Model):
    class Meta:
        verbose_name_plural = 'children'
        perms = (('change_children', 'Can change children'),)

【讨论】:

    【解决方案2】:

    它很旧 - 但供将来参考 - 所需的行为现在开箱即用(Django 1.9)

    考虑这个具有适当权限的抽象模型:

    class DetailContentLifecycleClassModel (models.Model):
        class Meta:
            abstract=True
            permissions = (
                ('can_change_content', 'Change content of the model'),
                ('can_submit_for_approval', 'Ask for final check and publishing'),
                ('can_publish_content', 'Publish the model as a new version'),
            )
    

    这样继承时:

    class Test_Details (DetailContentLifecycleClassModel):
        name = models.CharField(max_length=200)
    
    class Test_Details2 (DetailContentLifecycleClassModel):
        name = models.CharField(max_length=200)
    

    权限创建如下:

    from playground.models import Test_Details
    from django.contrib.auth.models import User, Permission
    
    tmp = Permission.objects.filter()
    

    结果(这正是我们想要的):

    playground | test_ details | Can add test_ details
    playground | test_ details | Change content of the model
    playground | test_ details | Publish the model as a new version
    playground | test_ details | Ask for final check and publishing
    playground | test_ details | Can change test_ details
    playground | test_ details | Can delete test_ details
    playground | test_ details2 | Can add test_ details2
    playground | test_ details2 | Change content of the model
    playground | test_ details2 | Publish the model as a new version
    playground | test_ details2 | Ask for final check and publishing
    playground | test_ details2 | Can change test_ details2
    playground | test_ details2 | Can delete test_ details2
    

    【讨论】:

    • 并非如此。例如,调查auth_permission 的内容将显示codename 仍然是每个内容类型的原始can_change_content,而不是can_change_content_details2。您自己的示例仅显示应用程序、类和描述文本的列表(这也将受益于包含类上下文名称)。我目前正在尝试自己解决同样的问题。
    • @CarlMarshall 我相信我只是通过使用Default permissions. 完成了这一点,这会正确创建permission.codenames,但是我似乎对permission.name 没有任何控制权,但我也不在乎很多。
    【解决方案3】:

    另一种较新的方法是在基类的 Meta 中设置 default_permissions。

    另外请注意,在执行此操作时,您需要进行迁移以使其生效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 2020-04-12
      • 2016-03-12
      相关资源
      最近更新 更多