Package: django-permissionedforms
django-permissionedformsdjango-permissionedformsis an extension to Django's forms framework, allowing you to define forms where certain fields are shown or omitted according to the user's permissions.InstallationRun:pip install django-permissionedformsUsageTo add permission rules to a basic Django form, subclasspermissionedforms.PermissionedFormin place ofdjango.forms.Formand add an innerMetaclass:frompermissionedformsimportPermissionedFormclassPersonForm(PermissionedForm):first_name=forms.CharField()last_name=forms.CharField()classMeta:field_permissions={'last_name':'myapp.change_last_name'}field_permissionsis a dict, mapping field names to permission codenames. For each field listed, that field will only be included in the final form if the user has the specified permission, as defined by theuser.has_perm()method. See Django's documentation oncustom permissionsandprogrammatically creating permissionsfor details on how to set permissions up; alternatively, if you want to set a field as only available to superusers, you can use any arbitrary string (such as'superuser') as the codename, sincehas_permalways returns True for them.Then, when instantiating the form, pass the keyword argumentfor_user:form=PersonForm(for_user=request.user)This will result in a form where thelast_namefield is only present if the logged-in user has thechange_last_namepermission.The keyword argumentfor_useris optional, and if not passed, the form will behave as an ordinary form with all named fields available.For a ModelForm, the procedure is the same, except that you should inherit frompermissionedforms.PermissionedModelForminstead.field_permissionsis added alongside the existingMetaoptions:frompermissionedformsimportPermissionedModelFormclassCountryForm(PermissionedModelForm):classMeta:model=Countryfields=['name','description']field_permissions={'description':'tests.change_country_description'}form=CountryForm(instance=country,for_user=request.user)Integrating with other base form classesYou may wish to integrate the permission handling fromdjango-permissionedformsinto some other base form class, such asClusterFormfrom thedjango-modelclusterpackage. If that base form class is a straightforward subclass ofdjango.forms.Formordjango.forms.ModelForm, then using multiple inheritance to additionally inherit fromPermissionedFormorPermissionedModelFormshould work:fromfancyformsimportFancyForm# made up for example purposesfrompermissionedformsimportPermissionedFormclassFancyPermissionedForm(PermissionedForm,FancyForm):passHowever, this will fail if the base form class implements its own metaclass. In this case, you will need to define a new metaclass inheriting from both the existing one andpermissionedforms.PermissionedFormMetaclass:fromfancyformsimportFancyFormfrompermissionedformsimportPermissionedForm,PermissionedFormMetaclassFancyFormMetaclass=type(FancyForm)classFancyPermissionedFormMetaclass(PermissionedFormMetaclass,FancyFormMetaclass):passclassFancyPermissionedForm(PermissionedForm,FancyForm,metaclass=FancyPermissionedFormMetaclass):passThis could still fail if the base form class incorporates a custom Options class to allow it to accept its ownclass Metaoptions. If so, it will be necessary to define a new Options class, again using multiple inheritance to subclass both the existing Options class andpermissionedforms.PermissionedFormOptionsMixin, and then set this asoptions_classon the metaclass. The following recipe will work forClusterForm:frommodelcluster.formsimportClusterForm,ClusterFormMetaclass,ClusterFormOptionsfrompermissionedformsimportPermissionedForm,PermissionedFormMetaclass,PermissionedFormOptionsMixinclassPermissionedClusterFormOptions(PermissionedFormOptionsMixin,ClusterFormOptions):passclassPermissionedClusterFormMetaclass(PermissionedFormMetaclass,ClusterFormMetaclass):options_class=PermissionedClusterFormOptionsclassPermissionedClusterForm(PermissionedForm,ClusterForm,metaclass=PermissionedClusterFormMetaclass):passAcknowledgementsdjango-permissionedformswas developed as part ofWagtail's next-generation page editor, sponsored by Google.