Django: наследовать разрешения от абстрактных моделей? - PullRequest
4 голосов
/ 03 июня 2010

Можно ли наследовать разрешения от абстрактной модели в Django? Я не могу ничего найти об этом. Для меня это не работает!

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

РЕДАКТИРОВАТЬ: Не работает означает, что он молча терпит неудачу. Разрешение не создается, так как оно не существует в моделях, наследуемых от этого класса.

Ответы [ 6 ]

10 голосов
/ 09 июня 2010

Разрешения не наследуются, если дочерний класс также определяет свой собственный 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 = ....

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

2 голосов
/ 23 октября 2014

взгляните на следующую мета-реализацию, он добавляет разрешения на чтение для всех моделей django, которые устанавливают для MyModelMeta Class свой метакласс :

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 и установите для мета-класса Memeber значение MyModelMeta:

class MyAbstractModel(models.Model):
    __metaclass__ = MyModelMeta

    class Meta:
        abstract=True

Теперь создайте нормальную модель Django, например:

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

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

Мой обходной путь:

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
2 голосов
/ 05 июня 2010

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

1 голос
/ 06 июня 2010

Я пишу тест по вашей проблеме. Я использую django 1.2.1, и у меня отличный результат!

Если вы хотите добавить разрешение к вашей существующей модели из наследовать модель, каждый раз, когда вы изменяете их, вам нужно запустить "syncdb" Пример 100% работает. (В 1.2.1 без патча)

Теперь работает.

альтернативный текст 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 голосов
/ 04 декабря 2013

В моем случае явное наследование Meta не работало из-за юга. Смотрите этот билет .

django-admin.py syncdb --all исправил проблему.

...