2010-06-03 1 views
4

Возможно ли наследовать разрешения от абстрактной модели в Django? Я ничего не могу с этим поделать. Для меня это не работает!Django: Наследовать Перспекции из абстрактных моделей?

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

EDIT: Не работает означает, что он не может молча. Разрешение не создается, поскольку оно не существует на моделях, наследующих от этого класса.

+1

«не работает» означает, что именно? вы можете уточнить? – mawimawi

+0

См. Редактирование. и я не могу найти какую-либо документацию, если это должно работать или нет ... –

ответ

2

Это ссылка для решения проблемы: http://code.djangoproject.com/ticket/10686 Необходимо применить патч ... Но он действительно работает.

+0

Как я понимаю, разрешения также должны быть унаследованы без этого патча? (если не указаны явные разрешения для детей и% (класс) проблема) –

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

спасибо, приятно знать, что он должен работать так ... так что я должен выяснить, почему это не так! –

+0

Узнал, в чем проблема: если у дочернего класса есть собственный внутренний класс Meta (который не определяет никаких разрешений), разрешения не наследуются! –

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 = .... 

Нет необходимости устанавливать абстрактные к ложному в Meta класса ребенка, так как Django устанавливает его в родительском to False при обработке! http://docs.djangoproject.com/en/dev/topics/db/models/#meta-inheritance

+0

Это все еще имеет место в Django 1.10.5. Применили это же обходное решение, чтобы получить абстрактные разрешения, добавленные в унаследованные модели, иначе makemigrations не найдет разрешения. –

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 класса будет 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)   

создают абстрактные модели Джанго и установить мету-класс memeber к MyModelMeta:

class MyAbstractModel(models.Model): 
    __metaclass__ = MyModelMeta 

    class Meta: 
     abstract=True 

сейчас, создать нормальную модель Джанго, как так:

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

это сгенерирует разрешения на добавление/изменение/удаление_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)