2011-02-10 1 views
3

Я хочу определить некоторые пользовательские разрешения для абстрактного класса модели, которые затем будут унаследованы всеми дочерними классами, а вместо того, чтобы давать разрешениям имя общего объекта, которое может применяться к любому типу подкласса, я хотел бы по существу использовать verbose_name_plural свойство дочерней модели как часть имен прав и описания (например, ('view_classname', 'Can view classname')), эмуляция поведения Django по умолчанию.Как динамически назвать разрешения в классе абстрактной модели 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.)

+0

Это все еще проблема, но смутно позитивные новости для более свежих посетителей этого вопроса состоят в том, что этот вопрос получил некоторую работу над ним 6 месяцев назад, но пока не сделал его релизом (и мы на 1.10 .5 на момент написания). https://github.com/django/django/pull/6861#issuecomment-240427426 –

ответ

0

Не могли бы вы выполнить это с помощью декоратора класса вместо абстрактной модели класс?

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'),) 
0

Это старый - но для использования в будущем - желаемое поведение работает из коробки в настоящее время (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 
+0

Не совсем так. Исследование содержимого 'auth_permission' покажет, что' codename' по-прежнему будет оригинальным 'can_change_content' для каждого типа контента, а не' can_change_content_details2', например. В вашем собственном примере показан только список приложений, классов и текст описания (что также могло бы иметь применение в имени контекста класса). В настоящее время я пытаюсь решить эту проблему самостоятельно. –

+0

@CarlMarshall Я полагаю, что я просто выполнил это, используя [Разрешения по умолчанию.] (Https://docs.djangoproject.com/en/1.10/ref/models/options/#default-permissions). Это правильно создает имена разрешений.codenames Кажется, у меня нет никакого контроля над разрешением.name, но мне на самом деле все равно. – DrS

0

Другой новый способ сделать это, чтобы установить default_permissions в Мете на вашем базовом классе.

Также имейте в виду, что при выполнении этого вы должны выполнить и выполнить миграцию, чтобы он вступил в силу.