Package: django-fperms
The flexible permissions library uses a custom permission model, that when installed patches itself into the standard django authentication library.DocumentationThe full documentation is athttps://django-fperms.readthedocs.io.QuickstartInstall django-fperms:pip install django-fpermsAdd it to yourINSTALLED_APPS:INSTALLED_APPS=(...'fperms.apps.FPermsConfig',...)Out of the box you have access to several new permission types:generic: for general purpose project wide permissionsmodel: for per model permissions (similar to django default permissions)instance: for per instance permissions, similar to model permissions but specific per instancefield: for per model field permissions, similar to model permissions but specific per model field, work in progressYou can also create your own permission model subclassing the abstract base permission class:fperms.models.BasePermand setting thePERM_MODELvariable in your project settings with the path to your custom model. E.g....PERM_MODEL='fperms.models.Perm'...You can find an example of custom permission model athttps://github.com/formulka/django-fperms-iscoreUsageA superuser has for all intents and purposes permission to do everything. For regular users you can assign permissions directly or via a user group.Creating a new permission:You can create a new permission directly via its model or via a specially formated string:fromfpermsimportenumsfromfperms.modelsimportPermPerm.objects.create(type=enums.PERM_TYPE_GENERIC,codename='export',)Perm.objects.create_from_str('generic.export')Assigning a permission:You can assign existing permission via the custompermsmanager available for both User (including custom ones) and Group models. You can add single permission or multiple both directly via its instance or using the formated string:fromdjango.auth.modelsimportUser,Groupfromfperms.modelsimportPermperm_export=Perm.objects.create(type=enums.PERM_TYPE_GENERIC,codename='export',)perm_import=Perm.objects.create(type=enums.PERM_TYPE_GENERIC,codename='import',)user=User.objects.get(pk=1)user.fperms.add_perm(perm_export)user.fperms.add_perm(perms=[perm_export,perm_import])group=Group.objects.get(pk=1)group.fperms.add_perm(perms=['generic.export','generic.import'])By default if said permission does not exist, it will raise an exception. You can override this behavior by settingPERM_AUTO_CREATEvariable in your project settings toTrue, assigning a permission will then create it as well if it does not exist.Retrieving permission instance:You can get a permission instance directly from the model or via the string representation.perm=Perm.objects.get(type=enums.PERM_TYPE_GENERIC,codename='export')perm=Perm.objects.get_from_str('generic.export')Checking permission:You can check whether the user or group has a required permission viahas_permmethod of thepermsmanager again using both the permission instance or the string representation....perm=Perm.objects.create(type=enums.PERM_TYPE_GENERIC,codename='export',)assertuser.fperms.has_perm(perm)assertuser.fperms.has_perm('generic.export')Built in perm typesgenericgeneric permission useful for project wide permissionstype is defined asfperms.enums.PERM_TYPE_GENERIC, it is the default permission typeit requirestypeandcodenamefields (type being default only the codename is actually required)string representation is'generic.<codename>'...# equivalent results:Perm.objects.create(codename='export',)Perm.objects.create_from_str('generic.export')modelmodel level permission analogous to the builtin django permissionstype is defined asfperms.enums.PERM_TYPE_MODELit requirestype,content_typeandcodenamefieldsdjango admin is using codenamesadd,changeanddeletefor its inner workingsstring representation is'model.<app_label>.<module_name>.<codename>'fromfpermsimportenumsfromfprems.utilsimportget_content_type...# equivalent results:Perm.objects.create(type=enums.PERM_TYPE_MODEL,content_type=get_content_type(Article),codename='add',)Perm.objects.create_from_str('model.articles.Article.add')objectmodel level permission specific per objecttype is defined asfperms.enums.PERM_TYPE_OBJECTit requirestype,content_type,object_idandcodenamefieldsdjango admin is using codenamesadd,changeanddeletefor its inner workingsstring representation is'object.<app_label>.<module_name>.<codename>'fromfpermsimportenumsfromfprems.utilsimportget_content_type...article=Article.objects.get(pk=1)# equivalent results:Perm.objects.create(type=enums.PERM_TYPE_OBJECT,content_type=get_content_type(Article),object_id=article.pk,codename='add',)Perm.objects.create_from_str('object.articles.Article.add',obj_id=article.pk)# creating multiple permissions for a single object at once is supportedPerm.objects.create_from_str(perms=['object.articles.Article.add','object.articles.Article.change','object.articles.Article.delete',],obj_id=article.pk)fieldmodel level permission specific per model fieldtype is defined asfperms.enums.PERM_TYPE_FIELDit requirestype,content_type,nameandcodenamefieldsstring representation is'field.<app_label>.<module_name>.<name>.<codename>'TODO:  this permission type is not fully implemented yetfromfpermsimportenumsfromfprems.utilsimportget_content_type...article=Article.objects.get(pk=1)# equivalent results:Perm.objects.create(type=enums.PERM_TYPE_FIELD,content_type=get_content_type(Article),name='name',codename='add',)Perm.objects.create_from_str('field.articles.Article.name.add')AdminFlexible permisssions support django admin interface, to enable them you need to first update the list of authentication backends in your project settings:AUTHENTICATION_BACKENDS=['django.contrib.auth.backends.ModelBackend','fperms.backends.PermBackend',]and then simply subclass thefperms.admin.PermModelAdmininstead of the regularadmin.ModelAdmin:fromdjango.contribimportadminfromfperms.adminimportPermModelAdminfromarticles.modelsimportArticle@admin.register(Article)classArticleAdmin(PermModelAdmin):passTo enable per-instance permission support, setperms_per_instanceproperty of the admin class toTrue....@admin.register(Article)classArticleAdmin(PermModelAdmin):perms_per_instance=TrueUser still needs model level permission for each model it should be able to access via admin site.If theperms_per_instanceoption is set toTrue, author of a new instance will automatically receive the permission to update and delete said instance.
You can override this behavior by settingperms_per_instance_author_changeandperms_per_instance_author_deleteadmin properties respectively toFalse.Running TestsDoes the code actually work?source <YOURVIRTUALENV>/bin/activate
(myenv) $ pip install tox
(myenv) $ toxCreditsTools used in rendering this package:Cookiecuttercookiecutter-djangopackageHistory0.4.7 (2020-10-24)Added permission GroupFixed tests0.1.0 (2018-02-13)First release on PyPI.