【问题标题】:Django: Inherit Permissions from abstract models?Django:从抽象模型继承权限?
【发布时间】:2010-06-03 10:13:15
【问题描述】:

是否可以从 Django 中的抽象模型继承权限? 我真的找不到任何关于那的东西。对我来说这行不通!

class PublishBase(models.Model): 
    class Meta:
        abstract = True
        get_latest_by = 'created'
        permissions = (('change_foreign_items',
                        "Can change other user's items"),)

编辑:不工作意味着它会默默地失败。未创建权限,因为从此类继承的模型中不存在该权限。

【问题讨论】:

  • “不起作用”究竟是什么意思?能详细点吗?
  • 查看编辑。而且我找不到任何文档,如果它应该工作或不工作......

标签: django django-models abstract django-permissions


【解决方案1】:

如果子类也定义了自己的class Meta,则权限不会被继承。 我找到了以下解决方法,这样就不必在每个子模型上再次定义权限:

class AbstractBaseModel(models.Model):
    class Meta:
        abstract = True
        permissions = (("test_permission","test permission"),)


class SomeClass(AbstractBaseModel):
    name = models.CharField(max_length=255,verbose_name="Name")

    class Meta(AbstractBaseModel.Meta):
        verbose_name = ....

不需要在子 Meta 类中将 abstract 设置为 false,因为 Django 在处理时将其在父级中设置为 False! http://docs.djangoproject.com/en/dev/topics/db/models/#meta-inheritance

【讨论】:

  • 在 Django 1.10.5 中仍然是这种情况。已应用相同的解决方法来获取添加到继承模型的抽象权限,否则 makemigrations 找不到权限。
  • 我想在继承类中添加一些新权限。正确的做法是什么?
【解决方案2】:

这里是解决您问题的链接:http://code.djangoproject.com/ticket/10686 需要打补丁……但确实有效。

【讨论】:

  • 据我所知,权限也应该在没有这个补丁的情况下被继承?(如果没有在孩子中定义明确的权限,以及 %(class)s 问题)
【解决方案3】:

我的解决方法:

class AbstractModelBase(models.base.ModelBase):

    def __new__(cls, name, bases, attrs):
        new = super(AbstractModelBase, cls).__new__(cls, name, bases, attrs)
        new._meta.permissions += (("abstract_permission", "Abstract permission"),)
        return new


class AbstractModel(models.Model):
    __metaclass__ = AbstractModelBase

    class Meta:
        abstract = True

【讨论】:

    【解决方案4】:

    看看下面的元实现, 它为所有将 MyModelMeta Class 设置为 metaclass 的 django 模型添加了读取权限:

    class MyModelMeta(ModelBase):
        # add a read permission to each MyModelMeta model
        def __new__(cls, name, bases, attrs):
    
            Meta = None
    
            if "Meta" in attrs:
                Meta = attrs.get("Meta")
                if hasattr(Meta, "abstract") and getattr(Meta, "abstract"):
                    # if the class is abstract, don't create permissions for it, just return the class object            
                    return super(MyModelMeta, cls).__new__(cls, name, bases, attrs)
    
            if not Meta:
                # create a new Meta Class
                Meta = type('Meta', (object,), {})
    
            setattr(Meta, 'permissions',(("read_%s"%name.lower(), "Can read %s"%name.lower()),))
            attrs['Meta'] = Meta
            return super(MyModelMeta, cls).__new__(cls, name, bases, attrs)        
    

    创建一个抽象的 django 模型并将元类成员设置为 MyModelMeta:

    class MyAbstractModel(models.Model):
        __metaclass__ = MyModelMeta
    
        class Meta:
            abstract=True
    

    现在,像这样创建一个普通的 django 模型:

    class SomeModel(MyAbstractModel):
        someFieldName = models.CharField(max_length=256, db_index=True)
    

    这将生成默认的 add/change/delete_somemodel 权限,但也 它将添加一个新的 read_somemodel 权限。

    如果你也在使用 south,使用它来生成额外的权限:

    from django.db.models import get_app, get_models
    from django.contrib.auth.management import create_permissions
    
    create_permissions(get_app(app), get_models(), 2 if settings.DEBUG else 0)
    

    【讨论】:

      【解决方案5】:

      我为您的问题编写测试。 我用的是 django 1.2.1,效果很好!

      如果您想从继承模型向现有模型添加权限,则每次更改它们时都需要运行“syncdb”。 示例 100% 有效。(在没有补丁的 1.2.1 中)

      现在可以了。

      alt text http://img203.imageshack.us/img203/7500/permn.png

      示例:

      from django.db import models
      from django.contrib import admin
      
      class permissions(models.Model):
          class Meta:
              abstract = True
              permissions = (("test_permission","test permission"),)
      
      
      class SomeClass(permissions):
          name = models.CharField(max_length=255,verbose_name="Name")
      
      admin.site.register(SomeClass)
      

      【讨论】:

      • 谢谢,很高兴知道它应该像这样工作......所以我必须找出它为什么不起作用!
      • 找出问题所在:如果子类有自己的内部 Meta 类(没有定义任何权限),则权限不会被继承!
      【解决方案6】:

      在我的情况下,由于 South,显式继承 Meta 不起作用。见this ticket

      django-admin.py syncdb --all 解决了这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-22
        • 2018-03-07
        • 2013-10-21
        • 2013-05-15
        • 1970-01-01
        • 2023-03-05
        • 2016-08-30
        • 1970-01-01
        相关资源
        最近更新 更多