How to dynamically name permissions in a class of abstract models of Django?

I want to define some user permissions for an abstract model class that will then be inherited by all child classes, and instead of giving the permissions a common object name that can be applied to any type of subclass, I would like to use the property of the verbose_name_pluralchild model as part of the name and description of the permissions (e.g. ('view_classname', 'Can view classname')) emulating the default behavior of Django.

So, I would hope to do something like this (which does not work, since verbose_name_pluralit is not defined in this context):

class AbstractModel(models.Model):
    class Meta:
        abstract = True
        permissions = (
            (u'view_%ss' % verbose_name_plural, u'Can view %s' % verbose_name_plural),
        )

(This issue is also described in http://code.djangoproject.com/ticket/10686 , which includes a patch that implements dynamic replacement %(class)sin permission definitions, but this patch has never been accepted, and my production environment does not allow Django to be fixed.)

+3
source share
3 answers

Could you do this with a class decorator instead of an abstract model class?

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
source

This is old - but for future reference - the desired behavior now works out of the box (Django 1.9)

Consider this abstract model with the appropriate permissions:

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

When inheriting:

class Test_Details (DetailContentLifecycleClassModel):
    name = models.CharField(max_length=200)

class Test_Details2 (DetailContentLifecycleClassModel):
    name = models.CharField(max_length=200)

Perm are performed as follows:

from playground.models import Test_Details
from django.contrib.auth.models import User, Permission

tmp = Permission.objects.filter()

Result (this is exactly what was needed):

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
source

- default_permissions .

Also keep in mind that when doing this, you must complete and complete the migration for it to take effect.

0
source

Source: https://habr.com/ru/post/1791342/


All Articles