2010-06-03 106 views
4

是否有可能從Django中的抽象模型繼承權限? 我真的無法找到任何有關這方面的信息。對我來說這是行不通的!Django:從抽象模型繼承Permssions?

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

編輯:沒有工作意味着它靜靜地失敗。不會創建權限,因爲它不會存在於從此類繼承的模型上。

+1

「不工作」是指什麼?你能詳細說明嗎? – mawimawi 2010-06-03 11:20:09

+0

請參閱編輯。我找不到任何文檔,如果這是應該工作或不... – 2010-06-03 11:26:03

回答

2

這裏是鏈接爲您解決問題:http://code.djangoproject.com/ticket/10686 需要應用補丁......但它真的有效。

+0

因爲我得到它的權限也應該繼承沒有這個補丁?(如果沒有明確的權限定義在兒童和%(class)s問題) – 2010-06-05 19:37:47

1

我爲您的問題編寫測試。 我使用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) 
+0

謝謝,很高興知道它應該像這樣工作......所以我必須找出爲什麼它沒有! – 2010-06-05 22:37:18

+0

找出問題所在:如果子類有自己的內部Meta類(它沒有定義任何權限),則權限不會被繼承! – 2010-06-09 14:24:53

10

的權限不繼承,如果子類也定義了自己的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 = .... 

無需設置抽象爲false子元類,因爲Django的設置它的父在處理它時出錯! http://docs.djangoproject.com/en/dev/topics/db/models/#meta-inheritance

+0

在Django 1.10.5中,情況仍然如此。已應用此相同的解決方法來獲取添加到繼承模型的抽象權限,否則makemigrations找不到權限。 – 2017-02-07 14:32:01

2

我的解決方法:

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 
0

在我的情況下明確地繼承Meta並沒有因爲南的工作。見this ticket

django-admin.py syncdb --all修復了這個問題。

2

看看下面的元執行, 它增加了讀取權限到設置MyModelMeta類中的所有Django模型是thier 元類

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模型,並設置元類現在

class MyAbstractModel(models.Model): 
    __metaclass__ = MyModelMeta 

    class Meta: 
     abstract=True 

,創建一個普通的Django模型,像這樣:memeber到MyModelMeta

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

這樣會生成默認的add/change/delete_somemodel權限,而且還會 它會添加一個新的read_somemodel權限。

如果您還使用南下,用此來產生額外的權限:

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)