Skip to main content

Django extension for creating forms that vary according to user permissions

Project description

django-permissionedforms

django-permissionedforms is 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.

Installation

Run: pip install django-permissionedforms

Usage

To add permission rules to a basic Django form, subclass permissionedforms.PermissionedForm in place of django.forms.Form and add an inner Meta class:

from permissionedforms import PermissionedForm

class PersonForm(PermissionedForm):
    first_name = forms.CharField()
    last_name = forms.CharField()

    class Meta:
        field_permissions = {
            'last_name': 'myapp.change_last_name'
        }

field_permissions is 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 the user.has_perm() method. See Django's documentation on custom permissions and programmatically creating permissions for 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, since has_perm always returns True for them.

Then, when instantiating the form, pass the keyword argument for_user:

form = PersonForm(for_user=request.user)

This will result in a form where the last_name field is only present if the logged-in user has the change_last_name permission.

The keyword argument for_user is 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 from permissionedforms.PermissionedModelForm instead. field_permissions is added alongside the existing Meta options:

from permissionedforms import PermissionedModelForm

class CountryForm(PermissionedModelForm):
    class Meta:
        model = Country
        fields = ['name', 'description']
        field_permissions = {
            'description': 'tests.change_country_description'
        }

form = CountryForm(instance=country, for_user=request.user)

Integrating with other base form classes

You may wish to integrate the permission handling from django-permissionedforms into some other base form class, such as ClusterForm from the django-modelcluster package. If that base form class is a straightforward subclass of django.forms.Form or django.forms.ModelForm, then using multiple inheritance to additionally inherit from PermissionedForm or PermissionedModelForm should work:

from fancyforms import FancyForm  # made up for example purposes
from permissionedforms import PermissionedForm

class FancyPermissionedForm(PermissionedForm, FancyForm):
    pass

However, 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 and permissionedforms.PermissionedFormMetaclass:

from fancyforms import FancyForm
from permissionedforms import PermissionedForm, PermissionedFormMetaclass


FancyFormMetaclass = type(FancyForm)


class FancyPermissionedFormMetaclass(PermissionedFormMetaclass, FancyFormMetaclass):
    pass


class FancyPermissionedForm(PermissionedForm, FancyForm, metaclass=FancyPermissionedFormMetaclass):
    pass

This could still fail if the base form class incorporates a custom Options class to allow it to accept its own class Meta options. If so, it will be necessary to define a new Options class, again using multiple inheritance to subclass both the existing Options class and permissionedforms.PermissionedFormOptionsMixin, and then set this as options_class on the metaclass. The following recipe will work for ClusterForm:

from modelcluster.forms import ClusterForm, ClusterFormMetaclass, ClusterFormOptions
from permissionedforms import PermissionedForm, PermissionedFormMetaclass, PermissionedFormOptionsMixin


class PermissionedClusterFormOptions(PermissionedFormOptionsMixin, ClusterFormOptions):
    pass


class PermissionedClusterFormMetaclass(PermissionedFormMetaclass, ClusterFormMetaclass):
    options_class = PermissionedClusterFormOptions


class PermissionedClusterForm(PermissionedForm, ClusterForm, metaclass=PermissionedClusterFormMetaclass):
    pass

Acknowledgements

django-permissionedforms was developed as part of Wagtail's next-generation page editor, sponsored by Google.

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-permissionedforms-0.1.tar.gz (5.9 kB view details)

Uploaded Source

Built Distribution

django_permissionedforms-0.1-py2.py3-none-any.whl (5.7 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file django-permissionedforms-0.1.tar.gz.

File metadata

  • Download URL: django-permissionedforms-0.1.tar.gz
  • Upload date:
  • Size: 5.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.8.0

File hashes

Hashes for django-permissionedforms-0.1.tar.gz
Algorithm Hash digest
SHA256 4340bb20c4477fffb13b4cc5cccf9f1b1010b64f79956c291c72d2ad2ed243f8
MD5 cfb5cdeb602c00283ffc2bc5f929ac46
BLAKE2b-256 944b364fe61a161ead607dc6af311901ba8e62f537f8fdab94b5252cb6efe6d7

See more details on using hashes here.

File details

Details for the file django_permissionedforms-0.1-py2.py3-none-any.whl.

File metadata

  • Download URL: django_permissionedforms-0.1-py2.py3-none-any.whl
  • Upload date:
  • Size: 5.7 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.8.0

File hashes

Hashes for django_permissionedforms-0.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 d341a961a27cc77fde8cc42141c6ab55cc1f0cb886963cc2d6967b9674fa47d6
MD5 a64ad0256c4d87addb39bc9751de57b4
BLAKE2b-256 e65b216157ff053f955b15b9dcdc13bfb6e406666445164fee9e332e141be96d

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page